Compare commits

...

2 Commits

Author SHA1 Message Date
gct 4760bf3fd9 version2
3 months ago
gct b2a5c65d8a version1
3 months ago

24
.gitignore vendored

@ -0,0 +1,24 @@
# 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?

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

@ -1,2 +1,5 @@
# uml
# 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).

@ -0,0 +1,13 @@
<!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,25 @@
{
"name": "lesson1_vite",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"ant-design-vue": "3.2.14",
"axios": "1.2.1",
"element-plus": "2.2.19",
"pinia": "2.0.27",
"pinia-plugin-persist": "^1.0.0",
"vant": "4.0.0",
"vue": "^3.4.37",
"vue-router": "4"
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.1.2",
"vite": "^5.4.1"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 419 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

@ -0,0 +1 @@
<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>

After

Width:  |  Height:  |  Size: 1.5 KiB

@ -0,0 +1,21 @@
<script setup>
</script>
<template>
<router-view></router-view>
</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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

@ -0,0 +1 @@
<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>

After

Width:  |  Height:  |  Size: 496 B

@ -0,0 +1,16 @@
import { createApp } from 'vue'
import './style.css'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
//import App from './components/App.vue'
import App from './App.vue'
import router from './router'
import { PiniaVuePlugin,createPinia } from 'pinia'
import piniaPluginPersist from 'pinia-plugin-persist'
const app=createApp(App)
app.use(ElementPlus)
app.use(router)
const pinia=createPinia()
pinia.use(piniaPluginPersist)
app.use(pinia)
app.mount('#app')

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

@ -0,0 +1,133 @@
import { createRouter, createWebHashHistory } from "vue-router";
import { userStore } from "./store";
import { storeToRefs } from "pinia";
const router = createRouter({
history: createWebHashHistory(),
routes: [
{
path: '/',
redirect: 'login'
},
{
path: '/login',
name: 'Login',
component: () => import('./view/Login.vue'),
meta: { requiresAuth: false } // 不需要登录
},
{
path: '/register',
name: 'Register',
component: () => import('./view/Register.vue'),
meta: { requiresAuth: false } // 不需要登录
},
{
path: '/User',
name: 'User',
component: () => import("./view/user/Index.vue"),
redirect: "/User/Head",
children: [
{
path: 'Head',
name: 'Head',
component: () => import("./view/user/Home.vue"),
meta: { requiresAuth: true }
},
{
path: 'userProfile',
name: 'userProfile',
component: () => import("./view/user/userProfile.vue"),
meta: { requiresAuth: true }
},
{
path: 'OrderManagement',
name: 'OrderManagement',
component: () => import("./view/user/OrderManagement.vue"),
meta: { requiresAuth: true }
},
{
path: 'ExpressForm',
name: 'ExpressForm',
component: () => import("./view/user/ExpressForm.vue"),
meta: { requiresAuth: true }
},
{
path: 'Address',
name: 'Address',
component: () => import("./view/user/Address.vue"),
meta: { requiresAuth: true }
},
{
path: 'ShipmentQuery',
name: 'ShipmentQuery',
component: () => import("./view/user/ShipmentQuery.vue"),
meta: { requiresAuth: true }
},
{
path: 'CourierComplaint',
name: 'CourierComplaint',
component: () => import("./view/user/CourierComplaint.vue"),
meta: { requiresAuth: true }
},
]
},
{
path: '/Courier',
name: 'Courier',
component: () => import("./view/courier/index.vue"),
redirect: "/Courier/Home",
children: [
{
path: 'Home',
name: 'Home',
component: () => import("./view/courier/Home.vue"),
meta: { requiresAuth: true },
},
{
path: 'orderProcessing',
name: 'orderProcessing',
component: () => import("./view/courier/OrderProcessing.vue"),
meta: { requiresAuth: true },
},
{
path: 'deliveryTracking',
name: 'deliveryTracking',
component: () => import("./view/courier/DeliveryTracking.vue"),
meta: { requiresAuth: true },
},
{
path: 'orderHistory',
name: 'orderHistory',
component: () => import("./view/courier/OrderHistory.vue"),
meta: { requiresAuth: true },
},
{
path: 'feedback',
name: 'feedback',
component: () => import("./view/courier/Feedback.vue"),
meta: { requiresAuth: true },
}
]
}
]
});
router.beforeEach((to, from, next) => {
const store = userStore();
const { loginState } = storeToRefs(store);
console.log("路由守卫:", loginState.value);
// 如果路由的 meta.requiresAuth 为 false直接允许访问
if (to.meta.requiresAuth === false) {
next();
} else {
// 否则检查登录状态
if (loginState.value) {
next();
} else {
next({ name: "Login" });
}
}
});
export default router;

@ -0,0 +1,26 @@
import {
defineStore
} from "pinia";
export const userStore = defineStore('storeId', {
state: () => {
return {
loginState: false
}
},
getters: {},
actions: {
setLoginState(state) {
this.loginState = state
}
},
persist: {
enabled: true, // 开启数据缓存
strategies: [{
key: 'storeId', // 当前store的id
storage: localStorage, // 存储方式
paths: ['loginState'] // 指定要持久化的字段
}]
}
})

@ -0,0 +1,26 @@
import { defineStore } from 'pinia';
export const useUserStore = defineStore('user', {
state: () => ({
username: '用户',
email: 'user@example.com',
gender: '',
birthdate: new Date(),
phone: '',
selectedRegion: [],
}),
actions: {
updateProfile(profile) {
this.username = profile.username;
this.email = profile.email;
this.gender = profile.gender;
this.birthdate = profile.birthdate;
this.phone = profile.phone;
this.selectedRegion = profile.selectedRegion;
},
},
persist: {
key: 'user-profile', // 存储的键名
storage: localStorage, // 使用 localStorage 持久化
},
});

@ -0,0 +1,79 @@
: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;
}
}

@ -0,0 +1,191 @@
<template>
<div class="login-container">
<div class="login-box">
<div class="logo-container">
<img src="../assets/logo.png" alt="Logo" class="logo">
<h2 class="login-title">旭日快递</h2>
</div>
<el-form :model="loginForm" :rules="loginRules" ref="loginFormRef" label-width="80px" class="login-form">
<el-form-item label="用户名" prop="username">
<el-input v-model="loginForm.username" placeholder="请输入用户名" clearable></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input v-model="loginForm.password" type="password" placeholder="请输入密码" clearable></el-input>
</el-form-item>
<el-form-item label="登录身份" prop="role" >
<el-select v-model="loginForm.role" placeholder="请选择登录身份" clearable>
<el-option label="普通用户" value="user"></el-option>
<el-option label="管理员" value="admin"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit" class="login-button">登录</el-button>
</el-form-item>
</el-form>
<router-link to="/register">没有账号去注册</router-link>
</div>
</div>
</template>
<script setup>
import {
ref
} from 'vue';
import {
ElMessage
} from 'element-plus';
import {
useRouter
} from 'vue-router';
import {
storeToRefs
} from 'pinia';
import {
userStore
} from '../store';
//
const userData = ref([
{ username: 'test', password: '123', role: 'user' },
{ username: 'admin', password: 'admin', role: 'admin' }
]);
//
const loginForm = ref({
username: '',
password: '',
role: ''
});
//
const loginRules = ref({
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' }
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' }
],
role: [
{ required: true, message: '请选择登录身份', trigger: 'change' }
]
});
//
const loginFormRef = ref(null);
const router = useRouter();
const store = userStore()
const {
loginState
} = storeToRefs(store)
//
const onSubmit = () => {
if (loginFormRef.value) {
loginFormRef.value.validate((valid) => {
if (valid) {
const user = userData.value.find(u =>
u.username === loginForm.value.username &&
u.password === loginForm.value.password &&
u.role === loginForm.value.role
);
if (user) {
ElMessage({
message: '登录成功!',
type: 'success',
duration: 3000
});
store.setLoginState(true);
if (loginForm.value.role === 'admin') {
router.push('/Courier'); //
} else {
router.push('/User'); //
}
} else {
ElMessage.error('用户名、密码或登录身份错误');
}
} else {
ElMessage.error('请检查输入信息是否正确');
}
});
}
};
</script>
<style scoped>
/* 整体容器,居中显示,背景渐变 */
.login-container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background: linear-gradient(135deg, #6ab7ff, #ece9e6);
font-family: 'Arial', sans-serif;
}
/* 登录框样式 */
.login-box {
width: 400px;
padding: 40px;
background-color: white;
border-radius: 10px;
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
text-align: center;
}
/* Logo 区域 */
.logo-container {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 20px;
}
.logo {
width: 100px;
margin-bottom: 10px;
}
.login-title {
font-size: 24px;
color: #333;
font-weight: 600;
margin: 0;
}
/* 输入框和表单样式 */
.el-input {
border-radius: 8px;
border: 1px solid #dcdfe6;
}
.el-input:focus-within {
border-color: #409eff;
}
/* 按钮美化 */
.login-button {
width: 100%;
height: 45px;
font-size: 16px;
border-radius: 25px;
background-color: #409eff;
border-color: #409eff;
color: white;
box-shadow: 0 4px 10px rgba(64, 158, 255, 0.2);
transition: all 0.3s ease;
}
.login-button:hover {
background-color: #66b1ff;
border-color: #66b1ff;
box-shadow: 0 4px 12px rgba(64, 158, 255, 0.3);
}
/* 输入框外间距 */
.el-form-item {
margin-bottom: 20px;
}
</style>

@ -0,0 +1,178 @@
<template>
<div class="register-container">
<div class="register-box">
<!-- Logo 区域 -->
<div class="logo-container">
<img src="../assets/logo.png" alt="Logo" class="logo">
<h2 class="register-title">用户注册</h2>
</div>
<!-- 注册表单 -->
<el-form :model="registerForm" :rules="registerRules" ref="registerFormRef" label-width="100px" class="register-form">
<!-- 用户名 -->
<el-form-item label="用户名" prop="username">
<el-input v-model="registerForm.username" placeholder="请输入用户名" clearable></el-input>
</el-form-item>
<!-- 账号 -->
<el-form-item label="账号" prop="account">
<el-input v-model="registerForm.account" placeholder="请输入账号" clearable></el-input>
</el-form-item>
<!-- 密码 -->
<el-form-item label="密码" prop="password">
<el-input v-model="registerForm.password" type="password" placeholder="请输入密码" clearable></el-input>
</el-form-item>
<!-- 确认密码 -->
<el-form-item label="确认密码" prop="confirmPassword">
<el-input v-model="registerForm.confirmPassword" type="password" placeholder="请再次输入密码" clearable></el-input>
</el-form-item>
<!-- 注册按钮 -->
<el-form-item>
<el-button type="primary" @click="onSubmit" class="register-button">注册</el-button>
</el-form-item>
<router-link to="/Login">已有账号去登录</router-link>
</el-form>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { ElMessage } from 'element-plus';
//
const registerForm = ref({
username: '',
password: '',
confirmPassword: '',
account: ''
});
//
const validateAccount = (rule, value, callback) => {
const regex = /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$/;
if (!value) {
callback(new Error('请输入账号'));
} else if (!regex.test(value)) {
callback(new Error('账号必须包含字母和数字并且不少于8个字符'));
} else {
callback();
}
};
//
const validateConfirmPassword = (rule, value, callback) => {
if (value !== registerForm.value.password) {
callback(new Error('两次输入的密码不一致'));
} else {
callback();
}
};
//
const registerRules = ref({
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' }
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' }
],
confirmPassword: [
{ required: true, message: '请确认密码', trigger: 'blur' },
{ validator: validateConfirmPassword, trigger: 'blur' }
],
account: [
{ required: true, message: '请输入账号', trigger: 'blur' },
{ validator: validateAccount, trigger: 'blur' }
]
});
const registerFormRef = ref(null);
//
const onSubmit = () => {
registerFormRef.value.validate((valid) => {
if (valid) {
ElMessage.success('注册成功!');
} else {
ElMessage.error('请检查输入信息是否正确');
return false;
}
});
};
</script>
<style scoped>
/* 整体容器,居中显示,背景渐变 */
.register-container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background: linear-gradient(135deg, #6ab7ff, #ece9e6);
font-family: 'Arial', sans-serif;
}
/* 注册框样式 */
.register-box {
width: 400px;
padding: 40px;
background-color: white;
border-radius: 10px;
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
text-align: center;
}
/* Logo 区域 */
.logo-container {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 20px;
}
.logo {
width: 100px;
margin-bottom: 10px;
}
.register-title {
font-size: 24px;
color: #333;
font-weight: 600;
margin: 0;
}
/* 输入框和表单样式 */
.el-input {
border-radius: 8px;
border: 1px solid #dcdfe6;
}
.el-input:focus-within {
border-color: #409eff;
}
/* 按钮美化 */
.register-button {
width: 100%;
height: 45px;
font-size: 16px;
border-radius: 25px;
background-color: #409eff;
border-color: #409eff;
color: white;
box-shadow: 0 4px 10px rgba(64, 158, 255, 0.2);
transition: all 0.3s ease;
}
.register-button:hover {
background-color: #66b1ff;
border-color: #66b1ff;
box-shadow: 0 4px 12px rgba(64, 158, 255, 0.3);
}
/* 输入框外间距 */
.el-form-item {
margin-bottom: 20px;
}
</style>

@ -0,0 +1,162 @@
<template>
<div class="container">
<!-- 页面标题 -->
<el-row class="title-row">
<el-col :span="24">
<h2 class="title">配送状态查询</h2>
</el-col>
</el-row>
<!-- 查询条件 -->
<el-row :gutter="20" class="query-row">
<el-col :span="8">
<el-input
v-model="searchText"
placeholder="请输入订单编号或客户姓名"
@input="filterOrders"
clearable
class="custom-input"
>
<template #prepend>
<el-icon><search /></el-icon>
</template>
</el-input>
</el-col>
<el-col :span="8">
<el-select
v-model="selectedStatus"
placeholder="选择订单状态"
@change="filterOrders"
clearable
class="custom-select"
>
<el-option label="待接收" value="待接收" />
<el-option label="待配送" value="待配送" />
<el-option label="配送中" value="配送中" />
<el-option label="已完成" value="已完成" />
</el-select>
</el-col>
</el-row>
<!-- 订单列表 -->
<el-table :data="filteredOrders" class="custom-table" stripe>
<el-table-column prop="orderId" label="订单编号" width="150" />
<el-table-column prop="customerName" label="客户姓名" width="150" />
<el-table-column prop="pickupAddress" label="取件地址" width="250" />
<el-table-column prop="deliveryAddress" label="送达地址" width="250" />
<el-table-column prop="status" label="订单状态" width="150" />
</el-table>
</div>
</template>
<script setup>
import { ref } from "vue";
import { Search } from "@element-plus/icons-vue";
//
const orders = ref([
{
orderId: "123456",
customerName: "张三",
pickupAddress: "北京市朝阳区",
deliveryAddress: "北京市海淀区",
status: "待接收",
},
{
orderId: "123457",
customerName: "李四",
pickupAddress: "上海市浦东新区",
deliveryAddress: "上海市静安区",
status: "待配送",
},
{
orderId: "123458",
customerName: "王五",
pickupAddress: "广州市天河区",
deliveryAddress: "广州市越秀区",
status: "配送中",
},
{
orderId: "123459",
customerName: "赵六",
pickupAddress: "深圳市南山区",
deliveryAddress: "深圳市福田区",
status: "已完成",
},
]);
//
const searchText = ref("");
//
const selectedStatus = ref(null);
//
const filteredOrders = ref([...orders.value]);
//
const filterOrders = () => {
filteredOrders.value = orders.value.filter((order) => {
const matchesText =
!searchText.value ||
order.orderId.includes(searchText.value) ||
order.customerName.includes(searchText.value);
const matchesStatus =
!selectedStatus.value || order.status === selectedStatus.value;
return matchesText && matchesStatus;
});
};
</script>
<style scoped>
/* 容器样式 */
.container {
background-color: #f9f9f9;
padding: 20px;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
/* 标题样式 */
.title-row {
margin-bottom: 20px;
text-align: center;
}
.title {
font-size: 24px;
font-weight: bold;
color: #333;
margin: 0;
}
/* 查询行样式 */
.query-row {
margin-bottom: 20px;
}
.custom-input {
border-radius: 5px;
}
.custom-select {
border-radius: 5px;
}
/* 表格样式 */
.custom-table {
background: white;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.1);
}
.custom-table .el-table__header {
background-color: #f5f5f5;
font-weight: bold;
}
.custom-table .el-table__row:hover {
background-color: #f0f9ff;
transition: background-color 0.3s;
}
</style>

@ -0,0 +1,78 @@
<template>
<el-container>
<el-header>
<h2 class="title">客户反馈</h2>
</el-header>
<el-main>
<el-row class="feedback-list">
<el-col :span="24">
<h2>客户反馈列表</h2>
<el-table :data="feedbacks" style="width: 100%">
<el-table-column label="主题" prop="subject" width="150"></el-table-column>
<el-table-column label="反馈内容" prop="content" width="300" :show-overflow-tooltip="true"></el-table-column>
<el-table-column label="提交日期" prop="date" width="180"></el-table-column>
<el-table-column label="联系方式" prop="contact" width="150"></el-table-column>
</el-table>
</el-col>
</el-row>
</el-main>
</el-container>
</template>
<script setup>
import { ref } from 'vue';
const feedbacks = ref([
{
subject: '物流问题',
content: '我的包裹在运输过程中丢失了,请尽快处理。',
date: '2024-11-01',
contact: '12345678901'
},
{
subject: '服务建议',
content: '希望能增加实时物流跟踪功能。',
date: '2024-11-05',
contact: ''
}
]);
</script>
<style scoped>
/* 顶部标题样式 */
.title {
font-size: 28px;
font-weight: bold;
color: #2c3e50;
text-align: center;
padding: 15px 0;
background-color: #f5f7fa;
margin: 0;
}
/* 客户反馈列表容器 */
.feedback-list {
padding: 20px;
background: #f9f9f9;
}
/* 分区标题样式 */
.section-title {
font-size: 20px;
font-weight: bold;
color: #333;
margin-bottom: 20px;
text-align: left;
}
/* 表格样式 */
.el-table {
margin-top: 20px;
border-radius: 8px;
}
/* 表格行的 hover 效果 */
.el-table .el-table__row:hover {
background-color: #e8f0fe;
}
</style>

@ -0,0 +1,111 @@
<template>
<div class="home-page">
<!-- 欢迎横幅 -->
<section class="welcome-banner">
<h1>欢迎使用旭日快递管理系统</h1>
<p>在这里您可以管理快递用户和系统设置</p>
</section>
<!-- 统计信息卡片 -->
<section class="statistics">
<el-row :gutter="20">
<el-col :span="8">
<el-card class="stat-card">
<div class="stat-title">用户总数</div>
<div class="stat-value">{{ userCount }}</div>
</el-card>
</el-col>
<el-col :span="8">
<el-card class="stat-card">
<div class="stat-title">快递总数</div>
<div class="stat-value">{{ expressCount }}</div>
</el-card>
</el-col>
<el-col :span="8">
<el-card class="stat-card">
<div class="stat-title">进行中的订单</div>
<div class="stat-value">{{ ongoingOrders }}</div>
</el-card>
</el-col>
</el-row>
</section>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import { useRouter } from 'vue-router';
//
const userCount = ref(1024);
const expressCount = ref(5678);
const ongoingOrders = ref(321);
//
const router = useRouter();
const goToPage = (path) => {
router.push(path);
};
//
onMounted(() => {
// API
});
</script>
<style scoped>
.home-page {
padding: 20px;
background-color: #f9f9f9;
}
.welcome-banner {
text-align: center;
padding: 20px;
background-color: #409EFF;
color: white;
border-radius: 8px;
margin-bottom: 30px;
}
.welcome-banner h1 {
font-size: 24px;
margin: 0;
}
.welcome-banner p {
font-size: 16px;
margin: 5px 0 0;
}
.statistics {
margin-bottom: 30px;
}
.stat-card {
text-align: center;
padding: 20px;
}
.stat-title {
font-size: 18px;
color: #606266;
margin-bottom: 10px;
}
.stat-value {
font-size: 24px;
font-weight: bold;
color: #409EFF;
}
.quick-actions {
margin-top: 30px;
text-align: center;
}
.el-button {
width: 100%;
padding: 15px 0;
}
</style>

@ -0,0 +1,183 @@
<template>
<div id="app">
<!-- Top Navigation Bar -->
<el-header class="top-nav">
<div class="logo">
<img src="../../assets/logo.png" alt="Logo" class="logo-image" />
<span class="title">旭日快递管理系统</span>
</div>
<div class="user-controls">
<span class="welcome-message">欢迎您管理员</span>
<el-button type="text" class="logout-button" @click="logout">退</el-button>
</div>
</el-header>
<!-- Main Container -->
<el-container>
<!-- Sidebar -->
<el-aside width="220px" class="sidebar">
<el-menu
:default-active="activeSidebarMenu"
class="side-menu"
@select="handleSidebarMenuSelect"
router
>
<el-menu-item index="Home">
<el-icon><HomeFilled /></el-icon>
<span>首页</span>
</el-menu-item>
<el-submenu index="1">
<template #title>
<el-icon><Document /></el-icon>
<span>订单管理</span>
</template>
<el-menu-item index="orderProcessing">订单处理</el-menu-item>
<el-menu-item index="deliveryTracking">配送状态查询</el-menu-item>
<el-menu-item index="orderHistory">历史订单</el-menu-item>
</el-submenu>
<el-menu-item index="feedback">
<el-icon><message /></el-icon>
<span>客户反馈</span>
</el-menu-item>
</el-menu>
</el-aside>
<!-- Content Area -->
<el-main class="content-area">
<router-view></router-view>
</el-main>
</el-container>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { useRouter } from 'vue-router';
import { HomeFilled, Document, Message } from '@element-plus/icons-vue';
// Define active sidebar menu
const activeSidebarMenu = ref('Home');
const router = useRouter();
// Handle sidebar menu item selectionH
const handleSidebarMenuSelect = (index) => {
activeSidebarMenu.value = index;
router.push(index); // Navigate to selected route
};
// Logout function
const logout = () => {
// Clear user session or token (if any)
localStorage.removeItem('userToken'); // Example: Remove stored token
// Redirect to login page
router.push('/login');
};
</script>
<style scoped>
#app {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
font-family: 'Arial', sans-serif;
}
.top-nav {
display: flex;
justify-content: space-between;
padding: 0 30px;
background-color: #3b82f6;
color: white;
align-items: center;
height: 80px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.logo {
display: flex;
align-items: center;
}
.logo-image {
width: 50px;
margin-right: 15px;
}
.title {
font-size: 1.8em;
font-weight: bold;
}
.logout-button {
color: white;
font-size: 1em;
margin-left: 20px;
}
.sidebar {
background: linear-gradient(180deg, #e0f7fa, #ffffff);
padding-top: 20px;
border-right: 1px solid #ddd;
}
.side-menu {
height: 100%;
border-right: none;
}
.side-menu .el-menu-item,
.side-menu .el-submenu__title {
font-size: 16px;
padding: 15px 20px;
}
.side-menu .el-menu-item:hover,
.side-menu .el-submenu__title:hover {
background-color: #f0f9ff;
color: #3b82f6;
}
.content-area {
padding: 25px 35px;
background-color: #ffffff;
box-shadow: inset 0 0 15px rgba(0, 0, 0, 0.05);
border-radius: 8px;
margin: 20px;
overflow-y: auto;
}
.el-menu-item.is-active {
color: #3b82f6 !important;
background-color: #f0f9ff;
}
.user-controls {
display: flex;
align-items: center;
}
.welcome-message {
margin-right: 15px;
font-size: 1.1em;
}
@media (max-width: 768px) {
.top-nav {
flex-direction: column;
height: auto;
text-align: center;
}
.sidebar {
display: none;
}
.content-area {
margin: 10px;
padding: 15px;
}
}
</style>

@ -0,0 +1,283 @@
<template>
<el-container>
<el-header>
<h1 class="title">历史订单管理</h1>
</el-header>
<el-main>
<el-row class="history-orders">
<!-- 标题 -->
<el-col :span="24">
<el-row class="title">
<span class="history-label">历史订单</span>
</el-row>
</el-col>
<!-- 搜索和筛选 -->
<el-col :span="24">
<el-row :gutter="10" class="search-filter-row">
<el-col :span="10">
<el-input v-model="searchQuery" placeholder="搜索订单编号或收件人" @keyup.enter="searchOrders"></el-input>
</el-col>
<el-col :span="2">
<el-button type="primary" @click="searchOrders"></el-button>
</el-col>
<el-col :span="10">
<el-select v-model="statusFilter" placeholder="选择订单状态" @change="filterOrders">
<el-option label="全部" value=""></el-option>
<el-option label="已完成" value="已完成"></el-option>
<el-option label="运输中" value="运输中"></el-option>
<el-option label="已取消" value="已取消"></el-option>
</el-select>
</el-col>
</el-row>
</el-col>
<!-- 订单列表 -->
<el-col :span="24">
<el-table :data="filteredOrders" style="width: 100%">
<el-table-column label="订单编号" prop="orderId" width="150"></el-table-column>
<el-table-column label="寄件人" prop="sender" width="200"></el-table-column>
<el-table-column label="收件人" prop="receiver" width="200"></el-table-column>
<el-table-column label="下单日期" prop="orderDate" width="180"></el-table-column>
<el-table-column label="订单状态" prop="status" width="120">
<template #default="scope">
<el-tag :type="getStatusType(scope.row.status)" disable-transitions>
{{ scope.row.status }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="150">
<template #default="scope">
<el-button size="mini" @click="viewOrder(scope.row)"></el-button>
</template>
</el-table-column>
</el-table>
</el-col>
<!-- 订单详情弹框 -->
<el-dialog v-model="dialogVisible" title="订单详情" width="40%">
<el-form :model="selectedOrder" label-width="100px">
<el-form-item label="订单编号">
<el-input v-model="selectedOrder.orderId" disabled></el-input>
</el-form-item>
<el-form-item label="寄件人">
<el-input v-model="selectedOrder.sender" disabled></el-input>
</el-form-item>
<el-form-item label="收件人">
<el-input v-model="selectedOrder.receiver" disabled></el-input>
</el-form-item>
<el-form-item label="下单日期">
<el-input v-model="selectedOrder.orderDate" disabled></el-input>
</el-form-item>
<el-form-item label="订单状态">
<el-input v-model="selectedOrder.status" disabled></el-input>
</el-form-item>
<el-form-item label="寄件地址">
<el-input v-model="selectedOrder.senderAddress" disabled></el-input>
</el-form-item>
<el-form-item label="收件地址">
<el-input v-model="selectedOrder.receiverAddress" disabled></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">关闭</el-button>
</span>
</el-dialog>
</el-row>
</el-main>
</el-container>
</template>
<script setup>
import { ref, computed } from 'vue';
const dialogVisible = ref(false);
const selectedOrder = ref(null);
const searchQuery = ref('');
const statusFilter = ref('');
//
const orders = ref([
{
orderId: 'ORD001',
sender: '张三',
receiver: '李四',
orderDate: '2024-11-01',
status: '已完成',
senderAddress: '北京朝阳区',
receiverAddress: '上海浦东新区'
},
{
orderId: 'ORD002',
sender: '王五',
receiver: '赵六',
orderDate: '2024-11-05',
status: '运输中',
senderAddress: '广州天河区',
receiverAddress: '深圳南山区'
},
{
orderId: 'ORD003',
sender: '周七',
receiver: '孙八',
orderDate: '2024-10-28',
status: '已取消',
senderAddress: '成都武侯区',
receiverAddress: '杭州西湖区'
},
]);
//
const filteredOrders = computed(() => {
let result = orders.value;
if (searchQuery.value) {
result = result.filter(order =>
order.orderId.includes(searchQuery.value) ||
order.receiver.includes(searchQuery.value)
);
}
if (statusFilter.value) {
result = result.filter(order => order.status === statusFilter.value);
}
return result;
});
//
const getStatusType = (status) => {
switch (status) {
case '已完成':
return 'success';
case '运输中':
return 'info';
case '已取消':
return 'danger';
default:
return 'default';
}
};
//
const searchOrders = () => {
//
};
//
const filterOrders = () => {
//
};
//
const viewOrder = (order) => {
selectedOrder.value = { ...order }; //
dialogVisible.value = true;
};
</script>
<style scoped>
/* 页面整体布局调整 */
.history-orders {
padding: 20px;
background-color: #f9f9f9; /* 设置页面背景颜色 */
border-radius: 8px; /* 圆角效果 */
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); /* 添加阴影 */
}
/* 标题样式 */
.title {
font-size: 28px;
font-weight: bold;
color: #3a3a3a;
text-align: center; /* 居中标题 */
margin: 20px 0;
}
/* 历史订单标题 */
.history-label {
font-size: 20px;
font-weight: bold;
color: #333;
}
/* 表格样式 */
.el-table {
margin-top: 20px;
background-color: #ffffff; /* 表格背景颜色 */
border-radius: 8px;
overflow: hidden; /* 隐藏多余部分 */
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
/* 表头样式 */
.el-table th {
background-color: #f5f7fa;
color: #606266;
font-size: 14px;
font-weight: bold;
}
/* 表格行样式 */
.el-table .el-table__body tr:hover {
background-color: #eef5ff; /* 鼠标悬停效果 */
}
/* 标签样式 */
.el-tag {
font-size: 14px;
border-radius: 4px;
padding: 5px 10px;
}
/* 按钮样式 */
.el-button {
margin-left: 10px;
border-radius: 20px; /* 圆角按钮 */
}
/* 搜索框容器 */
.search-container {
margin-bottom: 20px;
}
/* 搜索和筛选区域样式 */
.search-filter-row {
margin-top: 20px;
}
.el-input, .el-button, .el-select {
margin-right: 10px;
border-radius: 4px; /* 统一圆角 */
}
/* 弹窗样式 */
.el-dialog {
border-radius: 10px;
}
.dialog-footer {
text-align: right;
}
.dialog-footer .el-button {
border-radius: 20px; /* 圆角关闭按钮 */
}
/* 响应式布局 */
@media (max-width: 768px) {
.search-filter-row {
flex-direction: column;
}
.el-col {
margin-bottom: 10px;
}
.title {
font-size: 22px;
}
.history-label {
font-size: 16px;
}
}
</style>

@ -0,0 +1,192 @@
<template>
<div class="container">
<!-- 页面标题 -->
<el-row class="title-row">
<el-col :span="24">
<h2 class="title">订单处理</h2>
</el-col>
</el-row>
<!-- 订单列表 -->
<el-table :data="orders" class="custom-table" stripe>
<el-table-column prop="orderId" label="订单编号" width="150" />
<el-table-column prop="customerName" label="客户姓名" width="150" />
<el-table-column prop="pickupAddress" label="取件地址" width="250" />
<el-table-column prop="deliveryAddress" label="送达地址" width="250" />
<el-table-column prop="status" label="订单状态" width="150">
<template #default="{ row }">
<el-select v-model="row.status" @change="handleStatusChange(row)" placeholder="请选择状态">
<el-option label="待接收" value="待接收" />
<el-option label="待配送" value="待配送" />
<el-option label="配送中" value="配送中" />
<el-option label="已完成" value="已完成" />
</el-select>
</template>
</el-table-column>
<el-table-column label="操作" width="200">
<template #default="{ row }">
<el-button type="link" @click="handleEditCustomer(row)">
修改顾客信息
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 修改顾客信息对话框 -->
<el-dialog v-model="dialogVisible" width="50%" title="修改顾客信息" class="custom-dialog">
<el-form :model="orderDetail" label-width="120px">
<el-form-item label="订单编号">
<el-input v-model="orderDetail.orderId" disabled />
</el-form-item>
<el-form-item label="客户姓名">
<el-input v-model="orderDetail.customerName" placeholder="请输入客户姓名" />
</el-form-item>
<el-form-item label="取件地址">
<el-input v-model="orderDetail.pickupAddress" placeholder="请输入取件地址" />
</el-form-item>
<el-form-item label="送达地址">
<el-input v-model="orderDetail.deliveryAddress" placeholder="请输入送达地址" />
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="saveCustomerInfo"></el-button>
</span>
</el-dialog>
</div>
</template>
<script setup>
import { ref } from "vue";
//
const orders = ref([
{
orderId: "123456",
customerName: "张三",
pickupAddress: "北京市朝阳区",
deliveryAddress: "北京市海淀区",
status: "待接收",
},
{
orderId: "123457",
customerName: "李四",
pickupAddress: "上海市浦东新区",
deliveryAddress: "上海市静安区",
status: "待配送",
},
{
orderId: "123458",
customerName: "王五",
pickupAddress: "广州市天河区",
deliveryAddress: "广州市越秀区",
status: "配送中",
},
]);
//
const orderDetail = ref({
orderId: "",
customerName: "",
pickupAddress: "",
deliveryAddress: "",
status: "",
});
//
const dialogVisible = ref(false);
//
const handleEditCustomer = (row) => {
orderDetail.value = { ...row }; // orderDetail
dialogVisible.value = true; //
};
//
const saveCustomerInfo = () => {
const index = orders.value.findIndex((order) => order.orderId === orderDetail.value.orderId);
if (index !== -1) {
orders.value[index] = { ...orderDetail.value }; //
alert("顾客信息已更新!");
dialogVisible.value = false; //
}
};
//
const handleStatusChange = (order) => {
alert(`订单 ${order.orderId} 状态已更改为:${order.status}`);
};
</script>
<style scoped>
/* 页面整体样式 */
.container {
background-color: #f9f9f9;
padding: 20px;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
/* 标题样式 */
.title-row {
margin-bottom: 20px;
}
.title {
font-size: 24px;
font-weight: bold;
color: #333;
text-align: center;
}
/* 表格样式 */
.custom-table {
background: white;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.1);
}
.custom-table .el-table__header {
background-color: #f5f5f5;
font-weight: bold;
}
.custom-table .el-table__row {
transition: background-color 0.3s;
}
.custom-table .el-table__row:hover {
background-color: #f0f9ff;
}
/* 对话框样式 */
.custom-dialog {
border-radius: 10px;
}
.dialog-footer {
text-align: right;
border-top: 1px solid #f0f0f0;
padding-top: 10px;
}
/* 按钮样式 */
.el-button {
border-radius: 5px;
}
.el-button--primary {
background-color: #409eff;
border-color: #409eff;
}
.el-button--primary:hover {
background-color: #66b1ff;
}
/* 表单输入框样式 */
.el-form-item {
margin-bottom: 20px;
}
</style>

@ -0,0 +1,193 @@
<template>
<el-row class="page">
<el-row class="header">
<h2>地址簿</h2>
<el-button type="primary" @click="openAddDialog"></el-button>
</el-row>
<!-- 遍历显示 contactList 中的每个联系人信息 -->
<el-row class="block-view" v-for="(item, index) in contactList" :key="index">
<!-- 联系人信息 -->
<el-row class="contact-view">
<el-row>
<span class="name">{{ item.name }}</span>
<span class="phone">{{ item.phone }}</span>
</el-row>
<el-row class="address">{{ item.address }}</el-row>
<!-- 操作图标删除和编辑 -->
<el-row class="contact-icon-view">
<el-icon @click="deleteByIndex(index)">
<Delete />
</el-icon>
<el-icon @click="modify(item, index)">
<Edit />
</el-icon>
</el-row>
</el-row>
<!-- 分割线 -->
<el-row class="line-view"></el-row>
</el-row>
<!-- 删除确认对话框 -->
<el-dialog v-model="dialogVisible" title="警告" width="500">
<span>确定要删除此联系人吗</span>
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="deleteByIndexConfirm()">
确定
</el-button>
</div>
</template>
</el-dialog>
<!-- 添加或编辑联系人对话框 -->
<el-dialog v-model="dialogFormVisible" :title="dialogTitle" width="500">
<el-form :model="form">
<el-form-item label="姓名" :label-width="formLabelWidth">
<el-input v-model="form.name" autocomplete="off" />
</el-form-item>
<el-form-item label="电话号码" :label-width="formLabelWidth">
<el-input v-model="form.phone" autocomplete="off" />
</el-form-item>
<el-form-item label="地址" :label-width="formLabelWidth">
<el-input v-model="form.address" autocomplete="off" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogFormVisible = false">取消</el-button>
<el-button type="primary" @click="confirmDialog">
确认
</el-button>
</div>
</template>
</el-dialog>
</el-row>
</template>
<script setup>
import { Delete, Edit } from '@element-plus/icons-vue';
import { reactive, ref } from 'vue';
//
const contactList = reactive([
{ name: "张三", phone: "12345678901", address: "福建省福州市鼓楼区洪山镇杨桥西路50号" },
{ name: "李四", phone: "23456789012", address: "海南省海口市龙华区金垦路世代雅居二期清泉居A5028" },
]);
const dialogVisible = ref(false);
const dialogFormVisible = ref(false);
const dialogTitle = ref("新增联系人");
let formIndex = -1;
//
const form = reactive({
name: "",
phone: "",
email: "",
address: "",
});
const formLabelWidth = '100px';
//
const openAddDialog = () => {
dialogTitle.value = "新增联系人";
dialogFormVisible.value = true;
Object.assign(form, { name: "", phone: "", email: "", address: "" });
formIndex = -1;
};
//
const modify = (item, index) => {
dialogTitle.value = "编辑联系人";
dialogFormVisible.value = true;
Object.assign(form, item);
formIndex = index;
};
//
const confirmDialog = () => {
if (formIndex === -1) {
contactList.push({ ...form });
} else {
contactList[formIndex] = { ...form };
}
dialogFormVisible.value = false;
};
//
const deleteByIndex = (index) => {
dialogVisible.value = true;
formIndex = index;
};
const deleteByIndexConfirm = () => {
contactList.splice(formIndex, 1);
dialogVisible.value = false;
};
</script>
<style scoped>
.page {
display: flex;
flex-direction: column;
width: 100%;
background-color: white;
padding: 20px;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}
.block-view {
display: flex;
flex-direction: column;
margin-bottom: 20px;
border-bottom: 1px solid #ebebeb;
}
.contact-view {
display: flex;
flex-direction: column;
padding: 10px 0;
}
.name {
font-size: large;
font-weight: 500;
}
.phone {
color: gray;
margin-left: 10px;
}
.email {
color: gray;
font-size: small;
margin-top: 5px;
}
.address {
color: darkgray;
font-size: small;
margin-top: 5px;
}
.contact-icon-view {
margin-top: 10px;
display: flex;
justify-content: space-around;
}
.line-view {
height: 0.5px;
width: 95%;
background-color: lightgray;
margin-top: 10px;
}
</style>

@ -0,0 +1,105 @@
<template>
<div class="complaint-form">
<h2>快递投诉</h2>
<el-form :model="form" :rules="formRules" label-width="120px" class="form-container">
<!-- 运单号输入框 -->
<el-form-item label="运单号" prop="trackingNumber">
<el-input v-model="form.trackingNumber" placeholder="请输入运单号" clearable></el-input>
</el-form-item>
<!-- 投诉内容输入框 -->
<el-form-item label="投诉内容" prop="complaintContent">
<el-input v-model="form.complaintContent" type="textarea" placeholder="请输入投诉内容" rows="4"></el-input>
</el-form-item>
<!-- 联系方式输入框 -->
<el-form-item label="联系方式" prop="contact">
<el-input v-model="form.contact" placeholder="请输入联系方式" clearable></el-input>
</el-form-item>
<!-- 提交按钮 -->
<el-form-item>
<el-button type="primary" @click="handleSubmit"></el-button>
</el-form-item>
</el-form>
<!-- 提交成功提示 -->
<el-alert v-if="submitSuccess" type="success" title="投诉提交成功!" show-icon></el-alert>
<!-- 错误提示 -->
<el-alert v-if="error" type="error" :title="error" show-icon></el-alert>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { ElForm, ElFormItem, ElInput, ElButton, ElAlert } from 'element-plus';
//
const form = ref({
trackingNumber: '',
complaintContent: '',
contact: ''
});
//
const submitSuccess = ref(false);
const error = ref(null);
//
const formRules = {
trackingNumber: [{ required: true, message: '请输入运单号', trigger: 'blur' }],
complaintContent: [{ required: true, message: '请输入投诉内容', trigger: 'blur' }],
contact: [
{ required: true, message: '请输入联系方式', trigger: 'blur' },
{ pattern: /^[0-9]{11}$/, message: '请输入有效的电话号码', trigger: 'blur' }
]
};
//
const handleSubmit = () => {
error.value = null; //
//
const formRef = ref(null);
formRef.value.validate((valid) => {
if (valid) {
//
// axios.post('/api/complaint', form.value)
//
submitSuccess.value = true;
setTimeout(() => {
submitSuccess.value = false; // 3
form.value = { trackingNumber: '', complaintContent: '', contact: '' }; //
}, 3000);
} else {
error.value = '请填写所有必填项';
}
});
};
</script>
<style scoped>
.complaint-form {
max-width: 600px;
margin: 50px auto;
padding: 20px;
background: #fff;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
border-radius: 8px;
text-align: center;
}
.form-container {
margin-bottom: 20px;
}
.el-alert {
margin-top: 20px;
}
h2 {
margin-bottom: 20px;
}
</style>

@ -0,0 +1,241 @@
<template>
<el-row class="main">
<!-- 发件人面板 -->
<el-row class="send-container">
<el-row class="panel send-panel send-panel1">
<el-row class="send-container">
<el-button class="send-btn"></el-button>
<el-row>
<el-button class="btn" @click="openAddressBook('sender')">簿</el-button>
<el-button class="btn" @click="autoFill('sender')"></el-button>
</el-row>
</el-row>
<el-form ref="formSender" label-width="auto" class="form" :model="sender" :rules="senderRules">
<el-form-item label="姓名" prop="name">
<el-input v-model="sender.name" placeholder="请填写发件人姓名"></el-input>
</el-form-item>
<el-form-item label="联系电话" prop="phone">
<el-input v-model="sender.phone" placeholder="请填写发件人联系电话"></el-input>
</el-form-item>
<el-form-item label="省市区" prop="region">
<el-input v-model="sender.region" placeholder="请填写发件人省市区"></el-input>
</el-form-item>
<el-form-item label="详细地址" prop="detail">
<el-input v-model="sender.detail" placeholder="请填写发件人详细地址"></el-input>
</el-form-item>
<el-form-item label="公司名称">
<el-input v-model="sender.company" placeholder="请填写发件人公司名称"></el-input>
</el-form-item>
</el-form>
</el-row>
<!-- 箭头图标 -->
<el-image class="arrow" src="/arrow.png"></el-image>
<!-- 收件人面板 -->
<el-row class="panel send-panel send-panel1">
<el-row class="send-container">
<el-button class="send-btn receive-btn"></el-button>
<el-row>
<el-button class="btn" @click="openAddressBook('receiver')">簿</el-button>
<el-button class="btn" @click="autoFill('receiver')"></el-button>
</el-row>
</el-row>
<el-form ref="formReceiver" label-width="auto" class="form" :model="receiver" :rules="receiverRules">
<el-form-item label="姓名" prop="name">
<el-input v-model="receiver.name" placeholder="请填写收件人姓名"></el-input>
</el-form-item>
<el-form-item label="联系电话" prop="phone">
<el-input v-model="receiver.phone" placeholder="请填写收件人联系电话"></el-input>
</el-form-item>
<el-form-item label="省市区" prop="region">
<el-input v-model="receiver.region" placeholder="请填写收件人省市区"></el-input>
</el-form-item>
<el-form-item label="详细地址" prop="detail">
<el-input v-model="receiver.detail" placeholder="请填写收件人详细地址"></el-input>
</el-form-item>
<el-form-item label="公司名称">
<el-input v-model="receiver.company" placeholder="请填写收件人公司名称"></el-input>
</el-form-item>
</el-form>
</el-row>
</el-row>
<!-- 寄件方式 -->
<el-row class="panel send-panel">
<el-text class="send-label">寄件方式</el-text>
<el-row>
<el-radio-group v-model="shippingMethod">
<el-radio :label="1">预约上门取件</el-radio>
<el-radio :label="0">自行联系快递员</el-radio>
</el-radio-group>
</el-row>
</el-row>
<!-- 下单按钮 -->
<el-row class="panel send-panel">
<el-button class="confirm-btn" @click="submitOrder"></el-button>
</el-row>
</el-row>
</template>
<script setup>
import { ref } from 'vue';
import { ElMessage } from 'element-plus'; //
const formSender = ref(null);
const formReceiver = ref(null);
//
const sender = ref({
name: '',
phone: '',
region: '',
detail: '',
company: ''
});
const receiver = ref({
name: '',
phone: '',
region: '',
detail: '',
company: ''
});
const shippingMethod = ref(1); //
//
const senderRules = {
name: [{ required: true, message: '请输入发件人姓名', trigger: 'blur' }],
phone: [{ required: true, message: '请输入发件人联系电话', trigger: 'blur' }],
region: [{ required: true, message: '请输入发件人省市区', trigger: 'blur' }],
detail: [{ required: true, message: '请输入发件人详细地址', trigger: 'blur' }]
};
const receiverRules = {
name: [{ required: true, message: '请输入收件人姓名', trigger: 'blur' }],
phone: [{ required: true, message: '请输入收件人联系电话', trigger: 'blur' }],
region: [{ required: true, message: '请输入收件人省市区', trigger: 'blur' }],
detail: [{ required: true, message: '请输入收件人详细地址', trigger: 'blur' }]
};
// 簿
const openAddressBook = (type) => {
console.log(`${type} 地址簿点击`);
};
const autoFill = (type) => {
console.log(`${type} 智能填写点击`);
};
//
const submitOrder = () => {
formSender.value.validate((senderValid) => {
if (!senderValid) {
ElMessage.error('请完整填写寄件人信息!');
return;
}
formReceiver.value.validate((receiverValid) => {
if (!receiverValid) {
ElMessage.error('请完整填写收件人信息!');
return;
}
ElMessage.success('下单成功!');
resetForm();
});
});
};
//
const resetForm = () => {
sender.value = {
name: '',
phone: '',
address: {
region: '',
detail: ''
},
company: ''
};
receiver.value = {
name: '',
phone: '',
address: {
region: '',
detail: ''
},
company: ''
};
shippingMethod.value = 1;
};
</script>
<style scoped>
.send-btn {
border-radius: 100%;
padding: 10px;
background-color: black;
color: white;
}
.receive-btn {
background-color: red;
color: white;
}
.btn {
background-color: white;
}
.send-container {
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.panel {
display: flex;
flex-direction: column;
background-color: white;
justify-content: center;
align-items: flex-start;
}
.send-panel {
margin-top: 10px;
padding: 10px;
width: 100%;
line-height: 40px;
}
.send-panel1 {
width: 40%;
align-items: center;
}
.form {
width: 80%;
margin-top: 10px;
}
.arrow {
width: 40px;
height: 10px;
}
.send-label {
font-weight: 600;
}
.confirm-btn {
background-color: royalblue;
color: white;
}
</style>

@ -0,0 +1,142 @@
<template>
<div class="user-home-page">
<section class="welcome-banner">
<h1>欢迎使用旭日快递用户系统</h1>
<p>在这里您可以查看快递状况下单快递</p>
</section>
<!-- 用户信息部分 -->
<section class="user-info">
<el-row :gutter="20">
<el-col :span="8">
<el-card class="user-card">
<div class="user-title">用户名</div>
<div class="user-value">{{ username }}</div>
</el-card>
</el-col>
<el-col :span="8">
<el-card class="user-card">
<div class="user-title">账户余额</div>
<div class="user-value">{{ balance }} </div>
</el-card>
</el-col>
<el-col :span="8">
<el-card class="user-card">
<div class="user-title">最近登录</div>
<div class="user-value">{{ lastLogin }}</div>
</el-card>
</el-col>
</el-row>
</section>
<!-- 快递状态部分 -->
<section class="express-status">
<el-row :gutter="20">
<el-col :span="8">
<el-card class="status-card">
<div class="status-title">最新快递</div>
<div class="status-value">{{ latestExpress }}</div>
<el-button type="text" @click="goToPage('/express/detail')"></el-button>
</el-card>
</el-col>
<el-col :span="8">
<el-card class="status-card">
<div class="status-title">当前订单</div>
<div class="status-value">{{ currentOrderStatus }}</div>
<el-button type="text" @click="goToPage('/express/ongoing')"></el-button>
</el-card>
</el-col>
<el-col :span="8">
<el-card class="status-card">
<div class="status-title">已完成订单</div>
<div class="status-value">{{ completedOrders }}</div>
<el-button type="text" @click="goToPage('/express/completed')"></el-button>
</el-card>
</el-col>
</el-row>
</section>
<!-- 常用功能区 -->
</div>
</template>
<script setup>
import { ref } from 'vue';
import { useRouter } from 'vue-router';
//
const username = ref('张三');
const balance = ref(100.5); //
const lastLogin = ref('2024年11月19日 10:00');
//
const latestExpress = ref('快递001正在运输中');
const currentOrderStatus = ref('快递002待取件');
const completedOrders = ref(25);
//
const router = useRouter();
const goToPage = (path) => {
router.push(path);
};
</script>
<style scoped>
.user-home-page {
padding: 20px;
background-color: #f9f9f9;
}
.user-info,
.express-status {
margin-bottom: 30px;
}
.user-card,
.status-card {
text-align: center;
padding: 20px;
border-radius: 10px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
.user-title,
.status-title {
font-size: 18px;
color: #606266;
margin-bottom: 10px;
}
.user-value,
.status-value {
font-size: 24px;
font-weight: bold;
color: #409EFF;
}
.quick-actions {
margin-top: 30px;
text-align: center;
}
.el-button {
width: 100%;
padding: 15px 0;
}
.el-row {
margin-top: 10px;
}
.el-card {
cursor: pointer;
}
.el-card:hover {
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
}
.welcome-banner h1 {
font-size: 24px;
margin: 0;
}
</style>

@ -0,0 +1,162 @@
<template>
<div id="app">
<!-- Top Navigation Bar -->
<el-header class="top-nav" mode="horizontal">
<div class="logo">
<img src="../../assets/logo.png" alt="Logo" class="logo-image">
<span class="title">旭日快递</span>
</div>
<div class="user-controls">
<span class="welcome-message">欢迎您158****1626</span>
<el-button type="text" class="logout-button" @click="logout">退</el-button>
</div>
</el-header>
<!-- Main Container -->
<el-container>
<!-- Sidebar -->
<el-aside width="200px" class="sidebar">
<el-menu :default-active="activeSidebarMenu" class="side-menu" @select="handleSidebarMenuSelect" router>
<el-menu-item index="Head">首页</el-menu-item>
<el-submenu index="1">
<template #title>快递管理</template>
<el-menu-item index="ExpressForm">寄快递</el-menu-item>
<el-menu-item index="OrderManagement">快递列表</el-menu-item>
<el-menu-item index="ShipmentQuery">运单查询</el-menu-item>
</el-submenu>
<el-submenu index="2">
<template #title>用户管理</template>
<el-menu-item index="userProfile">用户资料</el-menu-item>
<el-menu-item index="Address">地址簿</el-menu-item>
</el-submenu>
<el-menu-item index="CourierComplaint">快递投诉</el-menu-item>
</el-menu>
</el-aside>
<!-- Content Area -->
<el-main class="content-area">
<router-view></router-view>
</el-main>
</el-container>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { useRouter } from 'vue-router';
const activeTopMenu = ref('dashboard');
const activeSidebarMenu = ref('/home');
const router = useRouter();
// Top menu item selection handler
const handleTopMenuSelect = (index) => {
activeTopMenu.value = index;
};
// Sidebar menu item selection handler
const handleSidebarMenuSelect = (index) => {
activeSidebarMenu.value = index;
router.push(index); // Navigate to selected route
};
// Logout function
const logout = () => {
// Clear user session or token (if any)
localStorage.removeItem('userToken'); // Example: Remove stored token
// Redirect to login page
router.push('/login');
};
</script>
<style scoped>
#app {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.top-nav {
display: flex;
justify-content: space-between;
padding: 0 30px;
background-color: #409EFF;
color: white;
align-items: center;
height: 80px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.logo {
display: flex;
align-items: center;
}
.logo-image {
width: 40px;
margin-right: 10px;
}
.title {
font-size: 1.5em;
font-weight: bold;
}
.top-menu {
color: white;
}
.el-menu-item {
padding: 0 20px;
}
.logout-button {
color: white;
font-size: 1em;
margin-left: 20px;
}
.sidebar {
background-color: #f5f7fa;
padding: 20px 0;
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.1);
}
.side-menu {
height: 100%;
border-right: none;
}
.side-menu .el-menu-item,
.side-menu .el-submenu__title {
font-size: 16px;
padding: 15px 20px;
}
.side-menu .el-menu-item:hover,
.side-menu .el-submenu__title:hover {
background-color: #e5f1fb;
color: #409EFF;
}
.content-area {
padding: 20px 30px;
background-color: #ffffff;
box-shadow: inset 0px 0px 10px rgba(0, 0, 0, 0.05);
border-radius: 6px;
margin: 20px;
overflow-y: auto;
}
.el-menu-item.is-active {
color: #409EFF !important;
background-color: #e5f1fb;
}
.user-controls {
display: flex;
align-items: center;
}
</style>

@ -0,0 +1,240 @@
<template>
<el-row class="page">
<el-row class="header">
<h2>快递列表</h2>
</el-row>
<!-- 遍历显示 expressList 中的每个快递信息 -->
<el-row class="block-view" v-for="(item, index) in expressList" :key="index">
<!-- 顶部信息包括运单号和签收时间 -->
<el-row class="top">
<el-row>运单号{{ item.express_no }}</el-row>
<el-row class="top-time">签收时间{{ item.s_datetime }}</el-row>
</el-row>
<!-- 快递信息区域 -->
<el-row class="express-view">
<!-- 寄件人信息 -->
<el-row class="express-no-view">
<el-text class="city">{{ item.senderCity }}</el-text>
<el-text class="user">{{ item.senderName }}</el-text>
</el-row>
<!-- 箭头及签收状态 -->
<el-row class="express-no-view">
<el-image class="arrow" src="/arrow.png"></el-image>
<el-text class="sign">已签收</el-text>
</el-row>
<!-- 收件人信息 -->
<el-row class="express-no-view">
<el-text class="city">{{ item.receiveCity }}</el-text>
<el-text class="user">{{ item.receiveName }}</el-text>
</el-row>
<!-- 操作图标删除和编辑 -->
<el-row class="express-icon-view">
<el-icon @click="deleteByIndex(index)">
<Delete />
</el-icon>
<el-icon @click="modify(item,index)">
<Edit />
</el-icon>
</el-row>
</el-row>
<!-- 分割线 -->
<el-row class="line-view"></el-row>
</el-row>
<el-dialog v-model="dialogVisible" title="警告" width="500">
<span>确定要删除此条快递信息吗</span>
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="deleteByIndexConfirm()">
确定
</el-button>
</div>
</template>
</el-dialog>
<el-dialog v-model="dialogFormVisible" title="编辑快件表单" width="500">
<el-form :model="form">
<el-form-item label="寄件城市" :label-width="formLabelWidth">
<el-input v-model="form.senderCity" autocomplete="off" />
</el-form-item>
<el-form-item label="寄件人" :label-width="formLabelWidth">
<el-input v-model="form.senderName" autocomplete="off" />
</el-form-item>
<el-form-item label="收件城市" :label-width="formLabelWidth">
<el-input v-model="form.receiveCity" autocomplete="off" />
</el-form-item>
<el-form-item label="收件人" :label-width="formLabelWidth">
<el-input v-model="form.receiveName" autocomplete="off" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogFormVisible = false">取消</el-button>
<el-button type="primary" @click="modifyConfirm()">
确认
</el-button>
</div>
</template>
</el-dialog>
</el-row>
</template>
<script setup>
import {
Delete,
Edit
} from '@element-plus/icons-vue';
import {
reactive,ref
} from 'vue';
//
const expressList = reactive([{
express_no: "SF12313123123",
senderCity: "深圳市",
senderName: "高先生1",
receiveCity: "福州市",
receiveName: "叶先生",
s_datetime: "2024-11-11 11:11:11"
},
{
express_no: "SF22313123124",
senderCity: "广州市",
senderName: "王小姐",
receiveCity: "上海市",
receiveName: "张先生",
s_datetime: "2024-11-11 14:15:00"
},
{
express_no: "SF32313123125",
senderCity: "杭州市",
senderName: "李女士",
receiveCity: "北京市",
receiveName: "周女士",
s_datetime: "2024-11-12 09:30:00"
}
]);
const dialogVisible = ref(false)
let formIndex = -1
const deleteByIndex = index => {
dialogVisible.value = true
formIndex = index
}
const deleteByIndexConfirm = () => {
dialogVisible.value = false
expressList.splice(formIndex, 1)
}
const dialogFormVisible= ref(false)
const formLabelWidth = '140px'
const form = reactive({
"express_no": "",
"senderCity": "",
"senderName": "",
"receiveCity": "",
"receiveName": "",
"s_datetime": ""
})
const modify= (item,index)=>{
dialogFormVisible.value = true
form.senderCity = item.senderCity
form.senderName = item.senderName
form.receiveCity = item.receiveCity
form.receiveName = item.receiveName
formIndex = index
}
const modifyConfirm = ()=>{
dialogFormVisible.value = false
const item = expressList[formIndex]
item.senderCity = form.senderCity
item.senderName = form.senderName
item.receiveCity = form.receiveCity
item.receiveName = form.receiveName
}
</script>
<style scoped>
.page {
display: flex;
flex-direction: column;
width: 100%;
background-color: white;
padding: 20px;
line-height: 20px;
}
.header {
text-align: center;
margin-bottom: 20px;
}
.block-view {
width: 100%;
display: flex;
flex-direction: column;
margin-bottom: 20px;
border-bottom: 1px solid #ebebeb;
}
.top {
display: flex;
flex-direction: row;
justify-content: flex-start;
padding: 10px;
color: gray;
}
.top-time {
margin-left: 180px;
}
.express-view {
display: flex;
width: 100%;
justify-content: space-around;
padding: 10px 0;
}
.express-no-view {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
}
.city {
font-size: large;
font-weight: 500;
}
.user {
margin-top: 5px;
font-size: small;
color: gray;
}
.arrow {
width: 40px;
height: 10px;
}
.sign {
font-size: small;
margin-top: 5px;
color: red;
font-weight: bold;
}
.express-icon-view {
width: 10%;
display: flex;
justify-content: space-around;
align-items: center;
}
.line-view {
height: 0.5px;
width: 95%;
background-color: lightgray;
margin-top: 10px;
}
</style>

@ -0,0 +1,100 @@
<template>
<div class="shipment-query">
<h2>运单查询</h2>
<el-form :model="form" label-width="120px" class="query-form">
<!-- 运单号输入框 -->
<el-form-item label="运单号" prop="trackingNumber">
<el-input v-model="form.trackingNumber" placeholder="请输入运单号" clearable></el-input>
</el-form-item>
<!-- 查询按钮 -->
<el-form-item>
<el-button type="primary" @click="handleQuery"></el-button>
</el-form-item>
</el-form>
<!-- 查询结果展示 -->
<el-card v-if="shipment" class="shipment-info">
<p><strong>运单号</strong>{{ shipment.trackingNumber }}</p>
<p><strong>发货人</strong>{{ shipment.sender }}</p>
<p><strong>收货人</strong>{{ shipment.receiver }}</p>
<p><strong>当前状态</strong>{{ shipment.status }}</p>
<p><strong>预计到达</strong>{{ shipment.estimatedArrival }}</p>
</el-card>
<!-- 错误提示 -->
<el-alert v-if="error" type="error" :title="error" show-icon></el-alert>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { ElForm, ElFormItem, ElInput, ElButton, ElCard, ElAlert } from 'element-plus';
//
const form = ref({
trackingNumber: ''
});
const shipment = ref(null);
const error = ref(null);
//
const mockShipments = [
{
trackingNumber: 'SF12313123123',
sender: '高先生',
receiver: '叶先生',
status: '运输中',
estimatedArrival: '2024-11-18'
},
{
trackingNumber: 'SF45645645656',
sender: '陈先生',
receiver: '叶先生',
status: '运输中',
estimatedArrival: '2024-11-16'
}
];
//
const handleQuery = () => {
error.value = null; //
const trackingNumber = form.value.trackingNumber.trim();
if (!trackingNumber) {
error.value = '请输入有效的运单号';
shipment.value = null;
return;
}
//
const foundShipment = mockShipments.find(shipment => shipment.trackingNumber === trackingNumber);
if (foundShipment) {
shipment.value = foundShipment;
} else {
error.value = '未找到该运单号的信息';
shipment.value = null;
}
};
</script>
<style scoped>
.shipment-query {
max-width: 600px;
margin: 50px auto;
text-align: center;
}
.query-form {
margin-bottom: 20px;
}
.shipment-info {
margin-top: 20px;
text-align: left;
}
.el-alert {
margin-top: 20px;
}
</style>

@ -0,0 +1,176 @@
<template>
<el-row class="top">
<el-col :span="6" class="col">用户资料</el-col>
<el-col :span="6" class="col-exit">
<el-button type="text" @click="logout"></el-button>
</el-col>
</el-row>
<el-row class="body">
<el-image class="user-img" src="/user.png"></el-image>
<div class="user-info">
<e-text class="username">{{ username }}</e-text>
<e-text class="email">{{ email }}</e-text>
</div>
<el-form label-width="auto" style="max-width:600px">
<el-form-item label="性别">
<el-select placeholder="请选择性别" v-model="gender">
<el-option v-for="item in genderOptions" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="生日">
<el-date-picker v-model="birthdate" type="date" placeholder="请选择生日" :size="20" />
</el-form-item>
<el-form-item label="地区">
<el-cascader v-model="selectedRegion" :options="optionRegion" placeholder="请选择地区"></el-cascader>
</el-form-item>
<el-form-item label="电话">
<el-input v-model="phone" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="updateProfile"></el-button>
</el-form-item>
</el-form>
</el-row>
</template>
<script setup>
import {
ref
} from 'vue';
import { useUserStore } from '../../store/user';
const userStore = useUserStore();
const username = userStore.username;
const email = userStore.email;
const gender = ref(userStore.gender);
const birthdate = ref(userStore.birthdate);
const phone = ref(userStore.phone);
const selectedRegion = ref(userStore.selectedRegion);
const genderOptions = [{
value: '男',
label: '男'
},
{
value: '女',
label: '女'
},
];
const optionRegion = ref([{
value: 'beijing',
label: '北京',
children: [{
value: 'chaoyang',
label: '朝阳区',
children: [{
value: 'subdistrict1',
label: '某街道1'
},
{
value: 'subdistrict2',
label: '某街道2'
},
],
},
{
value: 'haidian',
label: '海淀区',
children: [{
value: 'subdistrict3',
label: '某街道3'
},
{
value: 'subdistrict4',
label: '某街道4'
},
],
},
],
},
{
value: 'shanghai',
label: '上海',
children: [{
value: 'pudong',
label: '浦东新区',
children: [{
value: 'subdistrict5',
label: '某街道5'
},
{
value: 'subdistrict6',
label: '某街道6'
},
],
}, ],
},
]);
const logout = () => {
//
console.log("已注销");
};
const updateProfile = () => {
userStore.updateProfile({
username: userStore.username,
email: userStore.email,
gender: gender.value,
birthdate: birthdate.value,
phone: phone.value,
selectedRegion: selectedRegion.value,
});
console.log('用户资料已更新');
};
</script>
<style>
.top {
background-color: white;
height: 50px;
display: flex;
justify-content: space-between;
align-items: center;
border-radius: 10px;
}
.col {
font-size: 20px;
padding-left: 20px;
}
.col-exit {
font-size: 12px;
padding-right: 20px;
text-align: right;
}
.body {
margin-top: 20px;
background-color: white;
display: flex;
flex-direction: column;
align-items: center;
padding: 20px;
border-radius: 10px;
}
.user-img {
width: 100px;
height: 100px;
border-radius: 50%;
margin-bottom: 20px;
}
.user-info {
margin-bottom: 20px;
text-align: center;
}
.username,
.email {
display: block;
font-size: 16px;
margin: 5px 0;
}
</style>

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

@ -0,0 +1,839 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@ant-design/colors@^6.0.0":
version "6.0.0"
resolved "https://registry.npmmirror.com/@ant-design/colors/-/colors-6.0.0.tgz#9b9366257cffcc47db42b9d0203bb592c13c0298"
integrity sha512-qAZRvPzfdWHtfameEGP2Qvuf838NhergR35o+EuVyB5XvSA98xod5r4utvi4TJ3ywmevm290g9nsCG5MryrdWQ==
dependencies:
"@ctrl/tinycolor" "^3.4.0"
"@ant-design/icons-svg@^4.2.1":
version "4.4.2"
resolved "https://registry.npmmirror.com/@ant-design/icons-svg/-/icons-svg-4.4.2.tgz#ed2be7fb4d82ac7e1d45a54a5b06d6cecf8be6f6"
integrity sha512-vHbT+zJEVzllwP+CM+ul7reTEfBR0vgxFe7+lREAsAA7YGsYpboiq2sQNeQeRvh09GfQgs/GyFEvZpJ9cLXpXA==
"@ant-design/icons-vue@^6.1.0":
version "6.1.0"
resolved "https://registry.npmmirror.com/@ant-design/icons-vue/-/icons-vue-6.1.0.tgz#f9324fdc0eb4cea943cf626d2bf3db9a4ff4c074"
integrity sha512-EX6bYm56V+ZrKN7+3MT/ubDkvJ5rK/O2t380WFRflDcVFgsvl3NLH7Wxeau6R8DbrO5jWR6DSTC3B6gYFp77AA==
dependencies:
"@ant-design/colors" "^6.0.0"
"@ant-design/icons-svg" "^4.2.1"
"@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#5b3329c9a58803d5df425e5785865881a81ca48d"
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#75b889cfaf9e35c2aaf42cf0d72c8e91719251db"
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#af4f2df7d02440286b7de57b1c21acfb2a6f257a"
integrity sha512-nq+eWrOgdtu3jG5Os4TQP3x3cLA8hR8TvJNjD8vnPa20WGycimcparWnLK4jJhElTK6SDyuJo1weMKO/5LpmLA==
dependencies:
"@babel/types" "^7.25.4"
"@babel/runtime@^7.10.5":
version "7.25.7"
resolved "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.25.7.tgz#7ffb53c37a8f247c8c4d335e89cdf16a2e0d0fb6"
integrity sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==
dependencies:
regenerator-runtime "^0.14.0"
"@babel/types@^7.25.4":
version "7.25.4"
resolved "https://registry.npmmirror.com/@babel/types/-/types-7.25.4.tgz#6bcb46c72fdf1012a209d016c07f769e10adcb5f"
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.0", "@ctrl/tinycolor@^3.4.1":
version "3.6.1"
resolved "https://registry.npmmirror.com/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz#b6c75a56a1947cc916ea058772d666a2c8932f31"
integrity sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==
"@element-plus/icons-vue@^2.0.6":
version "2.3.1"
resolved "https://registry.npmmirror.com/@element-plus/icons-vue/-/icons-vue-2.3.1.tgz#1f635ad5fdd5c85ed936481525570e82b5a8307a"
integrity sha512-XxVUZv48RZAd87ucGS48jPf6pKu0yV5UCg9f4FFwtrYxXOwWuVJo6wOvSLKEoMQKjv8GsX/mhP6UsC1lRwbUWg==
"@esbuild/aix-ppc64@0.21.5":
version "0.21.5"
resolved "https://registry.npmmirror.com/@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.npmmirror.com/@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.npmmirror.com/@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.npmmirror.com/@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.npmmirror.com/@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.npmmirror.com/@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.npmmirror.com/@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.npmmirror.com/@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.npmmirror.com/@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.npmmirror.com/@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.npmmirror.com/@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.npmmirror.com/@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.npmmirror.com/@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.npmmirror.com/@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.npmmirror.com/@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.npmmirror.com/@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.npmmirror.com/@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.npmmirror.com/@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.npmmirror.com/@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.npmmirror.com/@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.npmmirror.com/@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.npmmirror.com/@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#acad351d582d157bb145535db2a6ff53dd514b5c"
integrity sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==
"@floating-ui/core@^1.6.0":
version "1.6.8"
resolved "https://registry.npmmirror.com/@floating-ui/core/-/core-1.6.8.tgz#aa43561be075815879305965020f492cdb43da12"
integrity sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==
dependencies:
"@floating-ui/utils" "^0.2.8"
"@floating-ui/dom@^1.0.1":
version "1.6.11"
resolved "https://registry.npmmirror.com/@floating-ui/dom/-/dom-1.6.11.tgz#8631857838d34ee5712339eb7cbdfb8ad34da723"
integrity sha512-qkMCxSR24v2vGkhYDo/UzxfJN3D4syqSjyuTFz6C7XcpU1pASPRieNI0Kj5VP3/503mOfYiGY891ugBX1GlABQ==
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.npmmirror.com/@floating-ui/utils/-/utils-0.2.8.tgz#21a907684723bbbaa5f0974cf7730bd797eb8e62"
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#3188bcb273a414b0d215fd22a58540b989b9409a"
integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==
"@popperjs/core@npm:@sxzz/popperjs-es@^2.11.7":
version "2.11.7"
resolved "https://registry.npmmirror.com/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz#a7f69e3665d3da9b115f9e71671dae1b97e13671"
integrity sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==
"@rollup/rollup-android-arm-eabi@4.21.1":
version "4.21.1"
resolved "https://registry.npmmirror.com/@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.npmmirror.com/@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.npmmirror.com/@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.npmmirror.com/@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.npmmirror.com/@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.npmmirror.com/@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.npmmirror.com/@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.npmmirror.com/@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.npmmirror.com/@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.npmmirror.com/@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.npmmirror.com/@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.npmmirror.com/@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.npmmirror.com/@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.npmmirror.com/@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.npmmirror.com/@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#4d3ec02dbf280c20bfeac7e50cd5669b66f9108f"
integrity sha512-xGiIH95H1zU7naUyTKEyOA/I0aexNMUdO9qRv0bLKN3qu25bBdrxZHqA3PTJ24YNN/GdMzG4xkDcd/GvjuhfLg==
"@simonwep/pickr@~1.8.0":
version "1.8.2"
resolved "https://registry.npmmirror.com/@simonwep/pickr/-/pickr-1.8.2.tgz#96dc86675940d7cad63d69c22083dd1cbb9797cb"
integrity sha512-/l5w8BIkrpP6n1xsetx9MWPWlU6OblN5YgZZphxan0Tq4BByTCETL6lyIeY8lagalS2Nbt4F2W034KHLIiunKA==
dependencies:
core-js "^3.15.1"
nanopop "^2.1.0"
"@types/estree@1.0.5":
version "1.0.5"
resolved "https://registry.npmmirror.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4"
integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==
"@types/lodash-es@^4.17.6":
version "4.17.12"
resolved "https://registry.npmmirror.com/@types/lodash-es/-/lodash-es-4.17.12.tgz#65f6d1e5f80539aa7cfbfc962de5def0cf4f341b"
integrity sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==
dependencies:
"@types/lodash" "*"
"@types/lodash@*", "@types/lodash@^4.14.182":
version "4.17.12"
resolved "https://registry.npmmirror.com/@types/lodash/-/lodash-4.17.12.tgz#25d71312bf66512105d71e55d42e22c36bcfc689"
integrity sha512-sviUmCE8AYdaF/KIHLDJBQgeYzPBI0vf/17NaYehBJfYD1j6/L95Slh07NlyK2iNyBNaEkb3En2jRt+a8y3xZQ==
"@types/web-bluetooth@^0.0.16":
version "0.0.16"
resolved "https://registry.npmmirror.com/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz#1d12873a8e49567371f2a75fe3e7f7edca6662d8"
integrity sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==
"@vant/popperjs@^1.3.0":
version "1.3.0"
resolved "https://registry.npmmirror.com/@vant/popperjs/-/popperjs-1.3.0.tgz#e0eff017124b5b2352ef3b36a6df06277f4400f2"
integrity sha512-hB+czUG+aHtjhaEmCJDuXOep0YTZjdlRR+4MSmIFnkCQIxJaXLQdSsR90XWvAI2yvKUI7TCGqR8pQg2RtvkMHw==
"@vant/use@^1.4.3":
version "1.6.0"
resolved "https://registry.npmmirror.com/@vant/use/-/use-1.6.0.tgz#237df3091617255519552ca311ffdfea9de59001"
integrity sha512-PHHxeAASgiOpSmMjceweIrv2AxDZIkWXyaczksMoWvKV2YAYEhoizRuk/xFnKF+emUIi46TsQ+rvlm/t2BBCfA==
"@vitejs/plugin-vue@^5.1.2":
version "5.1.2"
resolved "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-5.1.2.tgz#f11091e0130eca6c1ca8cfb85ee71ea53b255d31"
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#326dfe3c92fa2b0f1dc9b39a948a231980253496"
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#90348fac1130e0bbd408b650635cb626b3b9df06"
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#954c3f6777bbbcca28771ba59b795f12f76ef188"
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#9ded18f6d9c8b2440039a58492cfff36fa1a7774"
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.npmmirror.com/@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#ec2d549f4b831cd03d0baabf7d77e840b8536000"
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#bead9085e9a1c5a446e27d74ffb450f9261cf097"
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#52678ba0b85f94400a0a9c8dd23ddef4dd65657d"
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#457401ef2b0f969156702061e56915acecc9fe2c"
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#552a6770098bfd556fa3e2c686c9d3b4f4cd94c2"
integrity sha512-q0xCiLkuWWQLzVrecPb0RMsNWyxICOjPrcrwxTUEHb1fsnvni4dcuyG7RT/Ie7VPTvnjzIaWzRMUBsrqNj/hhw==
"@vueuse/core@^9.1.0":
version "9.13.0"
resolved "https://registry.npmmirror.com/@vueuse/core/-/core-9.13.0.tgz#2f69e66d1905c1e4eebc249a01759cf88ea00cf4"
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.npmmirror.com/@vueuse/metadata/-/metadata-9.13.0.tgz#bc25a6cdad1b1a93c36ce30191124da6520539ff"
integrity sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==
"@vueuse/shared@9.13.0":
version "9.13.0"
resolved "https://registry.npmmirror.com/@vueuse/shared/-/shared-9.13.0.tgz#089ff4cc4e2e7a4015e57a8f32e4b39d096353b9"
integrity sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==
dependencies:
vue-demi "*"
ant-design-vue@3.2.14:
version "3.2.14"
resolved "https://registry.npmmirror.com/ant-design-vue/-/ant-design-vue-3.2.14.tgz#04684ef9b855380059582a76bc9dd3c937f0fcc3"
integrity sha512-v4qeZGpmONUOvz6lyp/fJVoVthqV16CiG1rGrUZVB2IgRjCy59y2/F+RA67ZSJmjGIvqsE+tLoPmjJ0HVXg9XA==
dependencies:
"@ant-design/colors" "^6.0.0"
"@ant-design/icons-vue" "^6.1.0"
"@babel/runtime" "^7.10.5"
"@ctrl/tinycolor" "^3.4.0"
"@simonwep/pickr" "~1.8.0"
array-tree-filter "^2.1.0"
async-validator "^4.0.0"
dayjs "^1.10.5"
dom-align "^1.12.1"
dom-scroll-into-view "^2.0.0"
lodash "^4.17.21"
lodash-es "^4.17.15"
resize-observer-polyfill "^1.5.1"
scroll-into-view-if-needed "^2.2.25"
shallow-equal "^1.0.0"
vue-types "^3.0.0"
warning "^4.0.0"
array-tree-filter@^2.1.0:
version "2.1.0"
resolved "https://registry.npmmirror.com/array-tree-filter/-/array-tree-filter-2.1.0.tgz#873ac00fec83749f255ac8dd083814b4f6329190"
integrity sha512-4ROwICNlNw/Hqa9v+rk5h22KjmzB1JGTMVKP2AKJBOCgb0yL0ASf0+YvCcLNNwquOHNX48jkeZIJ3a+oOQqKcw==
async-validator@^4.0.0, async-validator@^4.2.5:
version "4.2.5"
resolved "https://registry.npmmirror.com/async-validator/-/async-validator-4.2.5.tgz#c96ea3332a521699d0afaaceed510a54656c6339"
integrity sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
axios@1.2.1:
version "1.2.1"
resolved "https://registry.npmmirror.com/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.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
dependencies:
delayed-stream "~1.0.0"
compute-scroll-into-view@^1.0.20:
version "1.0.20"
resolved "https://registry.npmmirror.com/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz#1768b5522d1172754f5d0c9b02de3af6be506a43"
integrity sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg==
core-js@^3.15.1:
version "3.38.1"
resolved "https://registry.npmmirror.com/core-js/-/core-js-3.38.1.tgz#aa375b79a286a670388a1a363363d53677c0383e"
integrity sha512-OP35aUorbU3Zvlx7pjsFdu1rGNnD4pgw/CWoYzRY3t2EzoVT7shKHY1dlAy3f41cGIO7ZDPQimhGFTlEYkG/Hw==
csstype@^3.1.3:
version "3.1.3"
resolved "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81"
integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==
dayjs@^1.10.5, dayjs@^1.11.3:
version "1.11.13"
resolved "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.13.tgz#92430b0139055c3ebb60150aa13e860a4b5a366c"
integrity sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
dom-align@^1.12.1:
version "1.12.4"
resolved "https://registry.npmmirror.com/dom-align/-/dom-align-1.12.4.tgz#3503992eb2a7cfcb2ed3b2a6d21e0b9c00d54511"
integrity sha512-R8LUSEay/68zE5c8/3BDxiTEvgb4xZTF0RKmAHfiEVN3klfIpXfi2/QCoiWPccVQ0J/ZGdz9OjzL4uJEP/MRAw==
dom-scroll-into-view@^2.0.0:
version "2.0.1"
resolved "https://registry.npmmirror.com/dom-scroll-into-view/-/dom-scroll-into-view-2.0.1.tgz#0decc8522801fd8d3f1c6ba355a74d382c5f989b"
integrity sha512-bvVTQe1lfaUr1oFzZX80ce9KLDlZ3iU+XGNE/bz9HnGdklTieqsbmsLHe+rT2XWqopvL0PckkYqN7ksmm5pe3w==
element-plus@2.2.19:
version "2.2.19"
resolved "https://registry.npmmirror.com/element-plus/-/element-plus-2.2.19.tgz#c11cb84b35b7698b2f5fa7ec0fd98034f6861a9e"
integrity sha512-uN0gt9lUus/IHzu5J6vkbYoYJgUtU05osdtFv9RO27bHKOG5GN7dH6uA3OKfkQQ6R2sV8ZxY1rc9PH1X8Dgrow==
dependencies:
"@ctrl/tinycolor" "^3.4.1"
"@element-plus/icons-vue" "^2.0.6"
"@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#5d268ea5e7113ec74c4d033b79ea5a35a488fb48"
integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
esbuild@^0.21.3:
version "0.21.5"
resolved "https://registry.npmmirror.com/esbuild/-/esbuild-0.21.5.tgz#9ca301b120922959b766360d8ac830da0d02997d"
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.npmmirror.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
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#52f010178c2a4c117a7757cfe942adb7d2da4cac"
integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
follow-redirects@^1.15.0:
version "1.15.9"
resolved "https://registry.npmmirror.com/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.npmmirror.com/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.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
is-plain-object@3.0.1:
version "3.0.1"
resolved "https://registry.npmmirror.com/is-plain-object/-/is-plain-object-3.0.1.tgz#662d92d24c0aa4302407b0d45d21f2251c85f85b"
integrity sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==
"js-tokens@^3.0.0 || ^4.0.0":
version "4.0.0"
resolved "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
lodash-es@^4.17.15, lodash-es@^4.17.21:
version "4.17.21"
resolved "https://registry.npmmirror.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee"
integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==
lodash-unified@^1.0.2:
version "1.0.3"
resolved "https://registry.npmmirror.com/lodash-unified/-/lodash-unified-1.0.3.tgz#80b1eac10ed2eb02ed189f08614a29c27d07c894"
integrity sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==
lodash@^4.17.21:
version "4.17.21"
resolved "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
loose-envify@^1.0.0:
version "1.4.0"
resolved "https://registry.npmmirror.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
dependencies:
js-tokens "^3.0.0 || ^4.0.0"
magic-string@^0.30.10:
version "0.30.11"
resolved "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.11.tgz#301a6f93b3e8c2cb13ac1a7a673492c0dfd12954"
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.npmmirror.com/memoize-one/-/memoize-one-6.0.0.tgz#b2591b871ed82948aee4727dc6abceeeac8c1045"
integrity sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==
mime-db@1.52.0:
version "1.52.0"
resolved "https://registry.npmmirror.com/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.npmmirror.com/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#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8"
integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==
nanopop@^2.1.0:
version "2.4.2"
resolved "https://registry.npmmirror.com/nanopop/-/nanopop-2.4.2.tgz#b55482135be7e64f2d0f5aa8ef51a58104ac7b13"
integrity sha512-NzOgmMQ+elxxHeIha+OG/Pv3Oc3p4RU2aBhwWwAqDpXrdTbtRylbRLQztLy8dMMwfl6pclznBdfUhccEn9ZIzw==
normalize-wheel-es@^1.2.0:
version "1.2.0"
resolved "https://registry.npmmirror.com/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz#0fa2593d619f7245a541652619105ab076acf09e"
integrity sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==
picocolors@^1.0.1:
version "1.0.1"
resolved "https://registry.npmmirror.com/picocolors/-/picocolors-1.0.1.tgz#a8ad579b571952f0e5d25892de5445bcfe25aaa1"
integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==
pinia-plugin-persist@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/pinia-plugin-persist/-/pinia-plugin-persist-1.0.0.tgz#fc696f225527f30bd5955109fafadd43c725e888"
integrity sha512-M4hBBd8fz/GgNmUPaaUsC29y1M09lqbXrMAHcusVoU8xlQi1TqgkWnnhvMikZwr7Le/hVyMx8KUcumGGrR6GVw==
dependencies:
vue-demi "^0.12.1"
pinia@2.0.27:
version "2.0.27"
resolved "https://registry.npmmirror.com/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#d6104d3ba272d882fe18fc07d15dc2da62fa2681"
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.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
regenerator-runtime@^0.14.0:
version "0.14.1"
resolved "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f"
integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==
resize-observer-polyfill@^1.5.1:
version "1.5.1"
resolved "https://registry.npmmirror.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464"
integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==
rollup@^4.20.0:
version "4.21.1"
resolved "https://registry.npmmirror.com/rollup/-/rollup-4.21.1.tgz#65b9b9e9de9a64604fab083fb127f3e9eac2935d"
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"
scroll-into-view-if-needed@^2.2.25:
version "2.2.31"
resolved "https://registry.npmmirror.com/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.31.tgz#d3c482959dc483e37962d1521254e3295d0d1587"
integrity sha512-dGCXy99wZQivjmjIqihaBQNjryrz5rueJY7eHfTdyWEiR4ttYpsajb14rn9s5d4DY4EcY6+4+U/maARBXJedkA==
dependencies:
compute-scroll-into-view "^1.0.20"
shallow-equal@^1.0.0:
version "1.2.1"
resolved "https://registry.npmmirror.com/shallow-equal/-/shallow-equal-1.2.1.tgz#4c16abfa56043aa20d050324efa68940b0da79da"
integrity sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==
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#16b809c162517b5b8c3e7dcd315a2a5c2612b2af"
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#dc5e698cbd079265bc73e0377681a4e4e83f616e"
integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==
vant@4.0.0:
version "4.0.0"
resolved "https://registry.npmmirror.com/vant/-/vant-4.0.0.tgz#573e5bc5a98fbb452bf2069bc278e2c57edebbfc"
integrity sha512-s3FDA7mWfkgFBWq/8J09dQZETeCzfGT41289fTIcp7VEcME62zXEw+8S41+stJVjk8fNXYRvMXsGfcD7HTLpaQ==
dependencies:
"@vant/popperjs" "^1.3.0"
"@vant/use" "^1.4.3"
vite@^5.4.1:
version "5.4.2"
resolved "https://registry.npmmirror.com/vite/-/vite-5.4.2.tgz#8acb6ec4bfab823cdfc1cb2d6c53ed311bc4e47e"
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.npmmirror.com/vue-demi/-/vue-demi-0.14.10.tgz#afc78de3d6f9e11bf78c55e8510ee12814522f04"
integrity sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==
vue-demi@^0.12.1:
version "0.12.5"
resolved "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.12.5.tgz#8eeed566a7d86eb090209a11723f887d28aeb2d1"
integrity sha512-BREuTgTYlUr0zw0EZn3hnhC3I6gPWv+Kwh4MCih6QcAeaTlaIX0DwOVN0wHej7hSvDPecz4jygy/idsgKfW58Q==
vue-router@4:
version "4.4.5"
resolved "https://registry.yarnpkg.com/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-types@^3.0.0:
version "3.0.2"
resolved "https://registry.npmmirror.com/vue-types/-/vue-types-3.0.2.tgz#ec16e05d412c038262fc1efa4ceb9647e7fb601d"
integrity sha512-IwUC0Aq2zwaXqy74h4WCvFCUtoV0iSWr0snWnE9TnU18S66GAQyqQbRf2qfJtUuiFsBf6qp0MEwdonlwznlcrw==
dependencies:
is-plain-object "3.0.1"
vue@^3.4.37:
version "3.4.38"
resolved "https://registry.npmmirror.com/vue/-/vue-3.4.38.tgz#0ccbb64ed03ef3c4ab73e540793290b18e7c4236"
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"
warning@^4.0.0:
version "4.0.3"
resolved "https://registry.npmmirror.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3"
integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==
dependencies:
loose-envify "^1.0.0"
Loading…
Cancel
Save