完善页面效果

This commit is contained in:
LittleBoy 2024-01-09 22:25:12 +08:00
parent e8c0325526
commit ce9943bcd5
30 changed files with 1437 additions and 331 deletions

View File

@ -6,24 +6,26 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>营养与健康数据管理处理平台</title> <title>营养与健康数据管理处理平台</title>
<style> <style>
.app-init-loading{font-size:14px;line-height:1.5;background-color:#fff;color:#2d8cf0;align-items:center;justify-content:center;text-align:center;display:flex;height:100vh;position:fixed;inset:0} .app-init-loading{--primary-background:#f0f0f2;--primary-color-1:#2ec7a5;background:var(--primary-background);font-size:14px;line-height:1.5;color:var(--primary-color-1);align-items:center;justify-content:center;text-align:center;display:flex;height:100vh;position:fixed;inset:0}
@keyframes app-init-rotate{100%{transform:rotate(360deg)} @keyframes loading-jr03l3h4rn8{0%{transform:translate(-50%,-50%) rotate(0)}
100%{transform:translate(-50%,-50%) rotate(360deg)}
} }
@keyframes app-init-dash{0%{stroke-dasharray:1,200;stroke-dashoffset:0} .loading-jr03l3h4rn8 div{position:absolute;width:var(--size);height:var(--size);border:2px solid var(--primary-color-1);border-top-color:transparent;border-radius:50%}
50%{stroke-dasharray:89,200;stroke-dashoffset:-35px} .loading-jr03l3h4rn8 div{animation:loading-jr03l3h4rn8 1s linear infinite;top:var(--size);left:var(--size)}
100%{stroke-dasharray:89,200;stroke-dashoffset:-124px} .spinner-rolling{--size:40px;width:calc(var(--size) * 2);height:calc(var(--size) * 2 - 10px);display:inline-block;overflow:hidden;background:0 0}
} .loading-jr03l3h4rn8{width:100%;height:100%;position:relative;transform:translateZ(0) scale(1);backface-visibility:hidden;transform-origin:0 0}
.app-init-loading .circular{width:50px;height:50px;animation:app-init-rotate 2s linear infinite;margin:auto} .loading-jr03l3h4rn8 div{box-sizing:content-box}
.app-init-loading .path{stroke-dasharray:1,200;stroke-dashoffset:0;stroke-width:2px;stroke:#2d8cf0;animation:app-init-dash 1.5s ease-in-out infinite}
</style> </style>
</head> </head>
<body> <body>
<div id="app"> <div id="app">
<div class="app-init-loading"> <div class="app-init-loading">
<div class="app-init-inner"> <div class="app-init-inner">
<svg class="circular" viewbox="25 25 50 50"> <div class="spinner-rolling">
<circle class="path" cx="50" cy="50" r="20" fill="none"/> <div class="loading-jr03l3h4rn8">
</svg> <div></div>
</div>
</div>
<div class="description">初始化中...</div> <div class="description">初始化中...</div>
</div> </div>
</div> </div>

View File

@ -9,9 +9,9 @@
"preview": "vite preview" "preview": "vite preview"
}, },
"dependencies": { "dependencies": {
"ant-design-vue": "4.x",
"dayjs": "^1.11.10", "dayjs": "^1.11.10",
"pinia": "^2.1.7", "pinia": "^2.1.7",
"view-ui-plus": "^1.3.15",
"vue": "^3.4.0", "vue": "^3.4.0",
"vue-router": "4" "vue-router": "4"
}, },

View File

@ -1,42 +1,31 @@
<script setup lang="ts"> <script setup lang="ts">
import { ConfigProvider } from 'ant-design-vue'
import PageLoading from "./components/page-loading/index.vue"; import PageLoading from "./components/page-loading/index.vue";
import { useUserStore } from "./service/user-store.ts";
import {useUserStore} from "./service/user-store.ts";
import Login from "./components/login/index.vue"; import Login from "./components/login/index.vue";
// //
const store = useUserStore() const store = useUserStore()
//
// const MENU_LIST = [
// {title: '', name: 'product', icon: 'ios-cube'},
// {title: '', name: 'field', icon: 'ios-apps'},
// {title: '', name: 'product_value', icon: 'ios-paper'},
// {title: '', name: 'result', icon: 'ios-calculator'},
// ]
// const activeMenu = ref(MENU_LIST[0].name)
const themeConfig = {
token: { colorPrimary: '#2EC7A5', },
}
</script> </script>
<template> <template>
<div class="app-container"> <div class="app-container">
<PageLoading :class="{ hideLoading: store.userInit }"/> <PageLoading :class="{ hideLoading: store.userInit }" />
<Login v-if="store.userInit && (!store.userInfo || store.userInfo.uid < 1) " /> <Login v-if="store.userInit && (!store.userInfo || store.userInfo.uid < 1)" />
<template v-if="store.userInit"> <template v-if="store.userInit">
<router-view /> <ConfigProvider :theme="themeConfig">
<router-view />
</ConfigProvider>
</template> </template>
</div> </div>
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss">
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.hideLoading { .hideLoading {
background: rgba(255, 255, 255, 0); background: rgba(255, 255, 255, 0);
pointer-events: none; pointer-events: none;
@ -66,12 +55,6 @@ const store = useUserStore()
padding: 20px 50px; padding: 20px 50px;
} }
.app-logo {
padding: 10px;
margin-right: 50px;
display: flex;
align-items: center;
}
body { body {
background: #fff; background: #fff;
@ -84,4 +67,3 @@ body {
transition: filter 300ms; transition: filter 300ms;
} }
</style> </style>
./service/api/user.ts

4
src/app-config.ts Normal file
View File

@ -0,0 +1,4 @@
export const AppConfig = {
appName: '营养计算器管理后台',
appDescription: '临床营养制剂能量及营养素计算',
}

View File

@ -0,0 +1,69 @@
.btn {
display: inline-block;
margin-bottom: 0;
font-weight: 400;
text-align: center;
vertical-align: middle;
touch-action: manipulation;
cursor: pointer;
background-image: none;
border: 1px solid transparent;
white-space: nowrap;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
height: 40px;
padding: 0 15px;
font-size: 14px;
border-radius: 4px;
outline: none;
transition: color .2s linear, background-color .2s linear, border .2s linear, box-shadow .2s linear;
&.btn-primary {
color: #fff;
background-color: var(--primary-color-1);
border-color: var(--primary-color-1);
&:hover, &:active {
background-color: var(--primary-color-1-hover);
border-color: var(--primary-color-1-hover);
}
}
&.btn-loading {
pointer-events: none;
position: relative;
}
.icon-loading{
display: inline-block;
margin-right: 5px;
animation: loading-360 linear 1s infinite;
vertical-align: middle;
display: inline-flex;
align-items: center;
color: inherit;
font-style: normal;
line-height: 0;
text-align: center;
text-transform: none;
vertical-align: -0.125em;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
&.btn-block {
display: block;
width: 100%;
}
&.btn-circle,
&.btn-circle-outline {
border-radius: 32px;
}
&.btn-round,
&.btn-round-outline {
border-radius: 32px;
}
}

View File

@ -0,0 +1,29 @@
<script setup lang="ts">
import './btn-style.scss'
const props = defineProps<{
type?: 'primary' | 'default';
block?: boolean;
shape?: 'default' | 'circle' | 'round';
loading?: boolean;
}>()
const btnClass = {
'btn-primary': props.type == 'primary',
'btn-default': (!props.type || props.type == 'default'),
'btn-block': props.block,
'btn-circle': props.shape == 'circle',
'btn-round': props.shape == 'round',
'btn-loading': props.loading,
}
</script>
<template>
<button class="btn" :class="btnClass">
<span v-if="props.loading" class="icon-loading"></span>
<span><slot/></span>
</button>
</template>
<style scoped lang="scss">
</style>

View File

@ -0,0 +1,4 @@
import ButtonComponent from './button.vue';
console.log(ButtonComponent)
export const Button = ButtonComponent

View File

@ -1,32 +1,63 @@
<script lang="ts" setup> <script lang="ts" setup>
import {Login, UserName, Password, Submit, Message} from 'view-ui-plus';
import {useUserStore} from "../../service/user-store.ts"; import {useUserStore} from "../../service/user-store.ts";
import {BizError} from "../../core/errors.ts"; import {BizError} from "../../core/errors.ts";
import {ref} from "vue";
import {AppConfig} from "../../app-config.ts";
import leftImage from './login_pic.png'
import {Button} from "../button";
import {LoginModel} from "../../service/api/user";
const handleSubmit = (...e: any) => { const loading = ref(false)
const [valid, params] = e as [valid: true, params: any]; const message = ref('')
const store = useUserStore(); const params = ref<LoginModel>({
if (valid) { account: '',
store.login(params).catch((e: BizError) => Message.info(e.message)) password: '',
})
const isValid = () => {
const isValid = params.value.account && params.value.password
message.value = isValid ? '' : '请输入账号及密码'
return isValid;
}
const store = useUserStore();
const handleSubmit = () => {
// const [valid, params] = e as [valid: true, params: any];
if (isValid()) {
loading.value = true
store
.login(params.value)
.catch((e: BizError) => message.value = e.message)
.finally(() => loading.value = false)
} }
} }
</script> </script>
<template> <template>
<div class="mask"></div> <div class="mask"></div>
<div class="login-wrapper"> <div class="login-wrapper layout-center">
<div class="login-container"> <div class="login-container">
<div class="logo"> <div class="left-panel">
<img src="../../assets/images/logo.png" alt=""> <h1 class="app-name">{{ AppConfig.appName }}</h1>
<p class="app-desc">{{ AppConfig.appDescription }}</p>
<img :src="leftImage" alt="">
</div> </div>
<p class="desc">营养与健康数据管理处理平台</p> <div class="login-form-wrapper layout-center">
<Login @on-submit="handleSubmit"> <div class="form-container">
<UserName name="account" enter-to-submit/> <div class="form-title">账号登录</div>
<Password name="password" enter-to-submit/> <div class="login-form">
<div class="submit"> <div class="form-item">
<Submit/> <input type="text" v-model="params.account" placeholder="请输入账号">
</div>
<div class="form-item">
<input type="password" v-model="params.password" placeholder="请输入密码">
</div>
<div class="message-tips">{{ message }}</div>
<div class="submit">
<Button @click="handleSubmit" :loading="loading" type="primary" block shape="round">
<b>登录</b></Button>
</div>
</div>
</div> </div>
</Login> </div>
</div> </div>
</div> </div>
</template> </template>
@ -35,40 +66,133 @@ const handleSubmit = (...e: any) => {
height: 100vh; height: 100vh;
position: fixed; position: fixed;
inset: 0; inset: 0;
display: flex;
align-items: center;
text-align: center; text-align: center;
justify-content: center; background: var(--primary-background);
background: rgba(0, 0, 0, 0.3);
z-index: 101; z-index: 101;
} }
.logo { .login-container {
width: 800px;
max-width: 90%;
display: flex;
overflow: hidden;
border-radius: var(--primary-border-radius);
box-shadow: 0 0 5px rgba(0, 0, 0, 0.05);
}
.left-panel {
background: var(--primary-color-1);
color: white;
width: 50%;
padding: 50px 0px;
text-align: center;
img { img {
width: 200px; margin: 50px 20px 10px;
width: 90%;
} }
margin-bottom: 10px;
} }
.desc { .app-desc {
margin-bottom: 30px; margin-top: 10px;
color: #ccc;
} }
.submit { .login-form-wrapper {
background: white;
width: 50%;
transition: all 0.2s;
}
.submit{
margin-top: 20px;
}
.form-container {
width: 75%;
}
.form-title {
font-size: 16px;
font-weight: bold;
&:after {
content: ' ';
width: 30px;
height: 2px;
display: block;
margin: 5px auto;
background: var(--primary-color-1);
}
}
.login-form {
margin-top: 50px; margin-top: 50px;
} }
.login-container { .message-tips {
width: 300px; height: 30px;
line-height: 30px;
color: red;
text-align: left;
} }
.mask { .form-item {
position: fixed; margin-top: 20px;
inset: 0; input {
background: url("https://bing.biturl.top/?resolution=1920&format=image&index=0&mkt=zh-CN") #fff; outline: none;
z-index: 100; display: block;
filter: blur(5px); width: 100%;
border: none;
border-bottom: solid 1px #e8eaef;
padding: 5px;
transition: all 0.5s;
&:focus {
border-color: var(--primary-color-1);
}
}
} }
.origin {
//
//.logo {
// img {
// width: 200px;
// }
//
// margin-bottom: 10px;
//}
//
//.desc {
// margin-bottom: 30px;
// color: #ccc;
//}
//
//.submit {
// margin-top: 50px;
//}
//
}
@media screen and (max-width: 800px) {
.login-form-wrapper {
padding: 50px 0;
width: 100%;
}
.login-container {
display: block;
max-width: 100%;
border-radius: 0;
height: 100%;
background: #fff;
}
.left-panel {
width: 100%;
img {
width: 250px;
margin: 10px 0;
}
}
}
</style> </style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

View File

@ -0,0 +1,40 @@
import Notification from "./notification-group.vue";
import {h, render, VNode} from 'vue'
import {NotificationProps} from "./types";
let vNode: VNode | null = null;
function getInstance() {
if (!vNode) {
vNode = h(Notification, {
ref:'noticeNode'
})
let noticeWrapper = document.querySelector<HTMLDivElement>('.notice-wrapper-c')
if (!noticeWrapper) {
noticeWrapper = document.createElement('div')
noticeWrapper.classList.add('notice-wrapper-c')
document.body.appendChild(noticeWrapper)
}
render(vNode, noticeWrapper)
}
return vNode?.component?.exposed;
}
function showNotification(prop: NotificationProps) {
const instance = getInstance();
instance?.addNotice?.(prop)
}
export const message = {
show(content: string, title?: string,duration = 3) {
showNotification({
type: 'notice',
content,
title,
duration,
closable:true
})
}
}

View File

@ -0,0 +1,91 @@
<script setup lang="ts">
import {onBeforeMount, onMounted, ref} from "vue";
import {NotificationProps} from "./types";
const props = defineProps<NotificationProps>()
const noticeRef = ref<HTMLDivElement>()
const closeTimer = ref<number>()
const emits = defineEmits<{
(e: 'close'): void;
}>()
//
const close = () => {
clearCloseTimer();
emits('close')
}
const clearCloseTimer = () => {
if (closeTimer.value) {
clearTimeout(closeTimer.value);
closeTimer.value = undefined;
}
}
onMounted(() => {
console.log('开始进入哈')
if (props.duration && props.duration > 0) {
closeTimer.value = setTimeout(close, props.duration * 1000) as any
}
})
onBeforeMount(() => {
console.log('开始退出哈')
})
</script>
<template>
<div ref="noticeRef" class="notice-instance">
<div v-if="props.type == 'notice'" class="notice-inner">
<div class="notice-content-wrapper">
<div class="notice-custom-content notice-with-normal notice-with-desc">
<div v-if="props.title" class="notice-title">{{ props.title }}</div>
<div class="notice-content-text" v-html="props.content"></div>
</div>
</div>
<a class="notice-close" v-if="props.closable" @click="close"><i class="icon-close"></i></a>
</div>
<div v-else class="message-wrapper">
</div>
</div>
</template>
<style lang="scss">
.notice-instance {
background: #fff;
border-radius: var(--primary-border-radius);
overflow: hidden;
padding: 15px;
box-shadow: 0 1px 6px rgba(0, 0, 0, .2);
margin-bottom: 20px;
position: relative;
}
.notice-inner {
.notice-title {
font-size: 16px;
color: #17233d;
padding-right: 10px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.notice-content-text {
font-size: 14px;
color: #515a6e;
text-align: justify;
}
.notice-close {
position: absolute;
right: 10px;
top: 10px;
cursor: pointer;
}
}
.message-wrapper {
}
</style>

View File

@ -0,0 +1,44 @@
<script lang="ts" setup>
import {ref} from "vue";
import Notice from './notice.vue'
import {NotificationProps} from "./types";
const notices = ref<NotificationProps[]>([])
const addNotice = (prop: NotificationProps) => {
notices.value.push(prop)
}
const removeNotice = (index: number) => {
notices.value.splice(index, 1)
}
defineExpose({
addNotice,
})
</script>
<template>
<div class="notice-wrapper">
<transition-group name="fade">
<Notice
v-for="(n,index) in notices"
:key="index"
:closable="n.closable"
:content="n.content"
:title="n.title"
:type="n.type"
:duration="n.duration"
@close="removeNotice(index)"
/>
</transition-group>
</div>
</template>
<style lang="scss">
.notice-wrapper {
position: fixed;
right: 20px;
top: 20px;
max-width: 335px;
position: fixed;
}
</style>

View File

@ -0,0 +1,7 @@
export type NotificationProps = {
type: 'notice' | 'message';
title?: string;
content: string;
closable?: boolean;
duration?: number;
}

View File

@ -0,0 +1,27 @@
<script setup lang="ts">
const props = defineProps(["title", "description"]);
</script>
<template>
<div class="page-content-header">
<div class="page-content-title" v-html="props.title"></div>
<div class="page-content-desc" v-html="props.description"></div>
</div>
</template>
<style lang="scss">
.page-content-header {
margin-bottom: 20px;
}
.page-content-title {
font-size: 16px;
font-weight: bold;
margin-bottom: 3px;
}
.page-content-desc {
color: #ccc;
font-size: 13px;
}
</style>

View File

@ -1,110 +1,14 @@
<script setup lang="ts">
import { Icon, Spin } from 'view-ui-plus'
</script>
<template> <template>
<div class="page-loading"> <div class="app-init-loading">
<Spin fix> <div class="app-init-inner">
<!-- <div class="loader"> <div class="spinner-rolling">
<svg class="circular" viewBox="25 25 50 50"> <div class="loading-jr03l3h4rn8">
<circle class="path" cx="50" cy="50" r="20" fill="none" stroke-width="5" stroke-miterlimit="10"> <div></div>
</circle> </div>
</svg> </div>
</div> -->
<Icon type="ios-loading" size="40" class="demo-spin-icon-load"></Icon>
<div class="description">初始化中...</div> <div class="description">初始化中...</div>
</Spin> </div>
</div> </div>
<!-- <div class="app-init-loading">-->
<!-- <div class="app-init-inner">-->
<!-- <svg class="circular" viewbox="25 25 50 50">-->
<!-- <circle class="path" cx="50" cy="50" r="20" fill="none"/>-->
<!-- </svg>-->
<!-- <div class="description">初始化中...</div>-->
<!-- </div>-->
<!-- </div>-->
</template> </template>
<script setup lang="ts">
<style scoped lang="scss"> </script>
.page-loading {
height: 100vh;
background:#fff;
position:fixed;
inset:0;
z-index:9999;
transition: all 0.5s;
opacity: 1;
}
.description {
margin-top: 10px;
}
.demo-spin-col .circular {
width: 25px;
height: 25px;
}
.demo-spin-icon-load {
animation: ani-demo-spin 1s linear infinite;
}
@keyframes rotate {
to {
-webkit-transform: rotate(1turn);
transform: rotate(1turn)
}
}
@keyframes dash {
0% {
stroke-dasharray: 1, 200;
stroke-dashoffset: 0
}
50% {
stroke-dasharray: 89, 200;
stroke-dashoffset: -35
}
to {
stroke-dasharray: 89, 200;
stroke-dashoffset: -124
}
}
.loader {
color: #000;
}
.circular {
animation: rotate 2s linear infinite;
.path {
stroke-dasharray: 1, 200;
stroke-dashoffset: 0;
animation: dash 1.5s ease-in-out infinite, color 6s ease-in-out infinite;
stroke-linecap: round;
}
}
@keyframes ani-demo-spin {
from {
transform: rotate(0deg);
}
50% {
transform: rotate(180deg);
}
to {
transform: rotate(360deg);
}
}
.demo-spin-col {
height: 100px;
position: relative;
border: 1px solid #eee;
}
</style>

View File

@ -0,0 +1,8 @@
import Select from './select.vue'
import SelectItem from './select-item.vue'
export {
Select,
SelectItem
}

View File

@ -0,0 +1,11 @@
<script setup lang="ts">
</script>
<template>
</template>
<style scoped lang="scss">
</style>

View File

@ -0,0 +1,130 @@
<script setup lang="ts">
import {computed, ref} from "vue";
type SelectOption = {
label: string;
value: any;
}
const props = defineProps<{
modelValue: any;
options: SelectOption[];
trigger?: 'hover' | 'click';
}>()
const emits = defineEmits(['update:modelValue'])
const state = ref({
showDropdown: false
})
const onToggle = () => {
state.value.showDropdown = !state.value.showDropdown
}
const selectedOption = computed(() => {
if (!props.modelValue) {
return props.options[0]
} else {
return props.options.find(s => s.value == props.modelValue) || props.options[0]
}
})
const onSelect = (it: SelectOption) => {
onClickOutside()
emits('update:modelValue', it.value)
}
const onClickOutside = ()=>{
state.value.showDropdown = false;
}
</script>
<template>
<div class="select-wrapper" v-click-outside="onClickOutside">
<div class="select-default">
<div class="select-selection" @click.prevent.stop="onToggle">
<input type="hidden" v-model="props.modelValue">
<div class="select-selection-value" :class="{'focus':state.showDropdown}">
<span class="select-selected-value">{{ selectedOption.label }}</span>
<i class="icon-arrow-down select-arrow"></i>
</div>
</div>
<div class="select-dropdown" x-placement="bottom-start" v-show="state.showDropdown">
<ul class="select-dropdown-list">
<li
v-for="(it,itIndex) in props.options"
:key="itIndex"
class="select-item"
:class="{'select-item-selected':it.value == props.modelValue}"
@click.stop.prevent="onSelect(it)"
>
<span>{{ it.label }}</span>
</li>
</ul>
</div>
</div>
</div>
</template>
<style lang="scss">
.select-wrapper {
position: relative;
--select-height: 30px;
display: inline-block;
ul, li {
list-style: none;
padding: 0;
margin: 0;
}
.select-default {
}
.select-selection-value {
cursor: pointer;
height: var(--select-height);
line-height: var(--select-height);
padding: 0px 10px;
min-width: 100px;
display: flex;
align-items: center;
justify-content: space-between;
border: solid 1px #eee;
border-radius: var(--primary-border-radius);
&.focus{
border-color: var(--primary-color-1-hover);
}
}
.select-selected-value {
}
.select-arrow {
}
.select-dropdown {
position: absolute;
background-color: #fff;
will-change: top, left;
transform-origin: center top;
top: calc(var(--select-height) + 3px);
left: 0;
right: 0;
border-radius: var(--primary-border-radius);
box-shadow: 0 1px 5px rgba(0, 0, 0, .2);
padding: 5px 0;
}
.select-dropdown-list {
}
.select-item {
padding: 5px 10px;
cursor: pointer;
&:hover {
background-color: #efefef;
}
}
.select-item-selected {
color: var(--primary-color-1)
}
}
</style>

View File

@ -1,11 +1,14 @@
import { createApp } from 'vue' import { createApp } from 'vue'
import 'view-ui-plus/dist/styles/viewuiplus.css' // import 'view-ui-plus/dist/styles/viewuiplus.css'
import { createPinia } from 'pinia' import { createPinia } from 'pinia'
import App from './App.vue' import App from './App.vue'
import router from './router' import router from './router'
import './style.css' import './style.scss'
// import 'ant-design-vue/dist/reset.css';
import {ClickOutsideDirective} from "./service/click-outside.ts";
createApp(App) createApp(App)
.use(createPinia()) .use(createPinia())
.use(router) .use(router)
.directive('click-outside',ClickOutsideDirective)
.mount('#app') .mount('#app')

View File

@ -1,10 +1,14 @@
<script lang="ts" setup> <script lang="ts" setup>
import {routes} from "../router.ts"; import { routes } from "../router.ts";
import {useUserStore} from "../service/user-store.ts"; import { useUserStore } from "../service/user-store.ts";
import {computed} from "vue"; import { computed, ref } from "vue";
import {Dropdown, DropdownItem, DropdownMenu, Icon} from "view-ui-plus";
import { AppConfig } from "../app-config.ts";
import { Dropdown, Menu, MenuItem, Button } from "ant-design-vue";
import { DownOutlined } from "@ant-design/icons-vue"
// //
const store = useUserStore() const store = useUserStore()
const showLogo = ref(false)
// 访 // 访
const currentMenus = computed(() => { const currentMenus = computed(() => {
// //
@ -13,81 +17,142 @@ const currentMenus = computed(() => {
return !s.meta || !s.meta['role'] || store.userInfo?.role == s.meta.role; return !s.meta || !s.meta['role'] || store.userInfo?.role == s.meta.role;
}) })
}) })
const handleMenuClick = ({ key }: { key: string }) => {
console.log('click menu', key)
if (key == 'logout') {
store.logout()
} else if (key == 'logout') {
}
}
</script> </script>
<template> <template>
<div class="layout"> <div class="layout">
<!-- 左侧菜单 --> <!-- 左侧菜单 -->
<div class="menu"> <div class="menu">
<div class="app-site-info">营养计算器</div> <div class="app-site-info">
<div class="app-logo" v-if="showLogo">
<img src="./../assets/images/logo-1.png" alt="">
</div>
<div class="app-name">营养计算器</div>
</div>
<div class="menu-link" v-for="r in currentMenus"> <div class="menu-link" v-for="r in currentMenus">
<router-link :to="(r.path||'/')">{{ r.meta?.title }}</router-link> <router-link class="menu-item" :to="(r.path || '/')">
<div class="menu-icon" :class="r.meta?.icon"></div>
<div>{{ r.meta?.title }}</div>
</router-link>
</div> </div>
</div> </div>
<!-- 右侧内容 --> <!-- 右侧内容 -->
<div class="app-main-container"> <div class="app-main-container">
<div class="header"> <div class="header">
<h1 class="app-name">营养计算器管理后台</h1> <h1 class="app-name">{{ AppConfig.appName }}</h1>
<div class="current-userinfo"> <div class="current-userinfo">
<Dropdown> <Dropdown>
<a href="javascript:void(0)"> <template #overlay>
下拉菜单 <Icon type="ios-arrow-down"></Icon> <Menu @click="handleMenuClick">
</a> <MenuItem key="modifyPassword">修改资料</MenuItem>
<template #list> <MenuItem key="logout">退出登录</MenuItem>
<DropdownMenu> </Menu>
<DropdownItem>驴打滚</DropdownItem>
<DropdownItem>炸酱面</DropdownItem>
<DropdownItem @click="store.logout()">退出登录</DropdownItem>
</DropdownMenu>
</template> </template>
<Button>
{{ store.userInfo?.nickname }}
<DownOutlined />
</Button>
</Dropdown> </Dropdown>
</div> </div>
</div> </div>
<div class="app-content"> <div class="app-content">
<router-view/> <router-view />
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss">
.layout{ .layout {
height: 100vh; height: 100vh;
display: flex; display: flex;
} }
.app-site-info{
color:#fff; .app-site-info {
line-height: 80px; color: #fff;
}
.menu{
background: #2ec7a5;
text-align: center; text-align: center;
} padding-bottom: 20px;
.menu-link{
a{ .app-name {
padding: 20px; font-size: 16px;
display: block; padding: 30px 10px 0;
color:#fff; }
&.router-link-exact-active{
background: #00ab99; .app-logo {
padding: 20px 0 0px;
img {
width: 50px;
} }
} }
} }
.app-main-container{
padding:20px; .menu {
background: #2ec7a5;
text-align: center;
}
.menu-link {
a {
padding: 20px;
display: block;
color: #fff;
&:hover {
background: #00ab9a4a;
}
&.router-link-exact-active {
background: #00ab99;
position: relative;
&::after {
//
content: ' ';
display: inline-block;
background: #00ab99;
width: 10px;
height: 10px;
position: absolute;
right: 0;
top: 50%;
transform: translateX(50%) translateY(-50%) rotate(45deg);
}
}
}
}
.menu-item {}
.menu-icon {
font-size: 26px;
}
.app-main-container {
padding: 30px;
overflow: auto; overflow: auto;
background: #f0f2f0; background: #f0f2f0;
flex: 1; flex: 1;
.header{
.header {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
margin-bottom: 20px; margin-bottom: 30px;
} }
} }
.app-content{
.app-content {
background: #fff; background: #fff;
border-radius: 5px; border-radius: 5px;
padding: 10px; padding: 20px;
} }
</style> </style>

View File

@ -1,3 +1,115 @@
<script setup lang="ts">
import { ref, h } from "vue";
import { SearchOutlined, PlusOutlined } from '@ant-design/icons-vue';
import {
Pagination, Select, SelectOption, Input, Button,
Space, Table,
} from 'ant-design-vue'
import PageHeader from '../components/page-header.vue'
import { fields, getProductValues } from "../service/data";
const searchParams = ref({
type: '',
name: ''
})
const current = ref(2);
const pageSize = ref<number>(20);
const columns = fields;
const allDataList = getProductValues();
console.log(allDataList)
const opts = [
{ label: '全部', value: '' },
{ label: '能量密度', value: 'power' },
{ label: 'Pro(g)', value: 'pro' },
{ label: 'Na(g)', value: 'na' },
]
</script>
<template> <template>
<h1>result</h1> <div class="data-fields-container">
</template> <PageHeader title="输入指标编辑" description="*输入指标: 作为输入参数进行计算,可对指标进行新增、编辑、删除操作。" />
<div class="search-form">
<Space :size="20">
<Space class="form-item">
<span>营养制剂</span>
<Input class="search-item" placeholder="请输入营养制剂" v-model:value="searchParams.name" />
</Space>
<Space class="form-item">
<span>类型</span>
<Select class="search-item" v-model:value="searchParams.type">
<SelectOption v-for="(it, opIndex) in opts" :key="opIndex" :value="it.value">{{ it.label }}
</SelectOption>
</Select>
</Space>
<Space class="form-item" :size="15">
<Button :icon="h(SearchOutlined)" type="primary">查询</Button>
<Button :icon="h(PlusOutlined)" class="btn-info">新增</Button>
</Space>
</Space>
</div>
<div class="search-result-table">
<div>
<table class="table">
<thead>
<tr>
<th>营养制剂</th>
<th v-for="th in columns">{{th.name}}</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(tr,rowIndex) in allDataList" :key="rowIndex">
<td>{{ tr.product.name }}</td>
<td v-for="it in tr.values">{{ it.value }}</td>
<td>
<Space :size="20">
<a>编辑</a>
<a>删除</a>
</Space>
</td>
</tr>
</tbody>
</table>
</div>
<div class="data-page">
<Pagination v-model:current="current" v-model:page-size="pageSize" :total="50"
:show-total="total => `共 ${total} 条`" />
</div>
</div>
</div>
</template>
<style lang="scss">
.search-form {
display: flex;
align-items: center;
margin: 10px 0;
.form-item {
display: inline-flex;
align-items: center;
}
}
.search-form {
.ant-input,
.ant-select .ant-select-selector {
background-color: #f7f8fa;
border: solid 1px transparent;
min-width: 100px;
&:focus,
&:hover {
border-color: var(--primary-color-1-hover);
}
}
}
.search-result-table {}
.data-page{
margin-top: 20px;
text-align: right;
}
</style>

View File

@ -1,3 +1,16 @@
<template> <template>
<p>输出计算</p> <p>输出计算</p>
<Button @click="showMessage">test</Button>
</template> </template>
<script setup lang="ts">
import Button from "../components/button/button.vue";
import {message} from "../components/message";
const showMessage = () => {
message.show(
'This notification does not automatically close, and you need to click the close button to close.',
'Notification title',
0
)
}
</script>

View File

@ -1,3 +1,115 @@
<script setup lang="ts">
import { ref, h } from "vue";
import { SearchOutlined, PlusOutlined } from '@ant-design/icons-vue';
import {
Pagination, Select, SelectOption, Input, Button,
Space, Table,
} from 'ant-design-vue'
import { fields, getProductValues } from "../service/data";
import PageHeader from '../components/page-header.vue'
const searchParams = ref({
type: '',
name: ''
})
const current = ref(2);
const pageSize = ref<number>(20);
const columns = fields;
const allDataList = getProductValues();
console.log(allDataList)
const opts = [
{ label: '全部', value: '' },
{ label: '能量密度', value: 'power' },
{ label: 'Pro(g)', value: 'pro' },
{ label: 'Na(g)', value: 'na' },
]
</script>
<template> <template>
<h1>user</h1> <div class="data-fields-container">
</template> <PageHeader title="登录账号管理" description="* 超级管理员: 拥有最高权限,可使用全部管理功能。管理员:普通管理权限,不可新建、删除、编辑账号。" />
<div class="search-form">
<Space :size="20">
<Space class="form-item">
<span>营养制剂</span>
<Input class="search-item" placeholder="请输入营养制剂" v-model:value="searchParams.name" />
</Space>
<Space class="form-item">
<span>类型</span>
<Select class="search-item" v-model:value="searchParams.type">
<SelectOption v-for="(it, opIndex) in opts" :key="opIndex" :value="it.value">{{ it.label }}
</SelectOption>
</Select>
</Space>
<Space class="form-item" :size="15">
<Button :icon="h(SearchOutlined)" type="primary">查询</Button>
<Button :icon="h(PlusOutlined)" class="btn-info">新增</Button>
</Space>
</Space>
</div>
<div class="search-result-table">
<div>
<table class="table">
<thead>
<tr>
<th>营养制剂</th>
<th v-for="th in columns">{{ th.name }}</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(tr, rowIndex) in allDataList" :key="rowIndex">
<td>{{ tr.product.name }}</td>
<td v-for="it in tr.values">{{ it.value }}</td>
<td>
<Space :size="20">
<a>编辑</a>
<a>删除</a>
</Space>
</td>
</tr>
</tbody>
</table>
</div>
<div class="data-page">
<Pagination v-model:current="current" v-model:page-size="pageSize" :total="50"
:show-total="total => `共 ${total} 条`" />
</div>
</div>
</div>
</template>
<style lang="scss">
.search-form {
display: flex;
align-items: center;
margin: 10px 0;
.form-item {
display: inline-flex;
align-items: center;
}
}
.search-form {
.ant-input,
.ant-select .ant-select-selector {
background-color: #f7f8fa;
border: solid 1px transparent;
min-width: 100px;
&:focus,
&:hover {
border-color: var(--primary-color-1-hover);
}
}
}
.search-result-table {}
.data-page {
margin-top: 20px;
text-align: right;
}
</style>

View File

@ -26,7 +26,8 @@ export const routes:RouteRecordRaw[] = [
path: '', path: '',
name: 'home', name: 'home',
meta: { meta: {
title: '输出计算' title: '输出计算',
icon:'icon-calculator'
}, },
component: () => import('./pages/result.vue') component: () => import('./pages/result.vue')
}, },
@ -34,7 +35,8 @@ export const routes:RouteRecordRaw[] = [
path: 'data', path: 'data',
name: 'data', name: 'data',
meta: { meta: {
title: '数据管理' title: '数据管理',
icon:'icon-input'
}, },
component: () => import('./pages/datas.vue') component: () => import('./pages/datas.vue')
}, },
@ -44,7 +46,8 @@ export const routes:RouteRecordRaw[] = [
component: () => import('./pages/user.vue'), component: () => import('./pages/user.vue'),
meta: { meta: {
role: 'root', role: 'root',
title: '用户管理' title: '用户管理',
icon:'icon-user'
} }
} }
] ]

View File

@ -0,0 +1,24 @@
import {DirectiveBinding, ObjectDirective} from "vue";
export const ClickOutsideDirective: ObjectDirective = {
beforeMount(el: HTMLElement, binding: DirectiveBinding) {
function documentHandler(e: any ) {
if (el.contains(e.target)) {
return false;
}
binding.value?.(e);
}
//@ts-ignore
el.__vueClickOutside__ = documentHandler;
document.addEventListener('click', documentHandler);
},
unmounted(el: HTMLElement) {
//@ts-ignore
document.removeEventListener('click', el.__vueClickOutside__);
//@ts-ignore
delete el.__vueClickOutside__;
},
}

View File

@ -2,7 +2,6 @@ import {defineStore} from "pinia"
import {onMounted, ref} from "vue" import {onMounted, ref} from "vue"
import {GetLoginInfo, LoginService} from "./api/user"; import {GetLoginInfo, LoginService} from "./api/user";
import {BizError} from "../core/errors.ts"; import {BizError} from "../core/errors.ts";
import router from "../router.ts";
import {sleep} from "../core/sleep.ts"; import {sleep} from "../core/sleep.ts";
type LoginParam = { type LoginParam = {
@ -26,6 +25,7 @@ export const useUserStore = defineStore('counter', () => {
// 登出 // 登出
const logout = async () => { const logout = async () => {
await sleep(1000);
localStorage.removeItem(LOGIN_SESSION_KEY) localStorage.removeItem(LOGIN_SESSION_KEY)
userInfo.value = undefined; userInfo.value = undefined;
} }
@ -42,13 +42,17 @@ export const useUserStore = defineStore('counter', () => {
userInfo.value = await GetLoginInfo(); userInfo.value = await GetLoginInfo();
} }
onMounted(() => { onMounted(() => {
getUserInfo().catch((e: BizError) => { getUserInfo().catch((e: BizError) => {
if (e.code == 401) { if (e.code == 401) {
router.replace(`/login?redirect=${router.currentRoute.value.path}`).then(() => console.log('401 show login')) //router.replace(`/login?redirect=${router.currentRoute.value.path}`).then(() => )
console.log('401 show login')
} }
}).finally(() => { }).finally(() => {
console.log('onMounted inited') console.log('onMounted inited')
userInit.value = true setTimeout(()=>{
userInit.value = true
},500)
}) })
}) })

View File

@ -1,11 +0,0 @@
:root {
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%;
}

210
src/style.scss Normal file
View File

@ -0,0 +1,210 @@
@font-face {
font-family: 'iconfont';
/* Project id 4404323 */
src: url('//at.alicdn.com/t/c/font_4404323_pubb123lqt.woff2?t=1704788291593') format('woff2'),
url('//at.alicdn.com/t/c/font_4404323_pubb123lqt.woff?t=1704788291593') format('woff'),
url('//at.alicdn.com/t/c/font_4404323_pubb123lqt.ttf?t=1704788291593') format('truetype');
}
@keyframes loading-360 {
0% {
transform: rotate(0)
}
100% {
transform: rotate(360deg)
}
}
:root {
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%;
--primary-background: #f0f0f2;
--primary-color-1: rgb(46, 199, 165);
--primary-color-1-hover: rgba(46, 199, 165, .9);
--primary-color-2: #3894ff;
--primary-color-2-hover: #3895ffbf;
--primary-border-radius: 3px;
}
[type=reset],
[type=submit],
button,
html [type=button] {
-webkit-appearance: button;
}
article,
aside,
blockquote,
body,
button,
dd,
details,
div,
dl,
dt,
fieldset,
figcaption,
figure,
footer,
form,
h1,
h2,
h3,
h4,
h5,
h6,
header,
hgroup,
hr,
input,
legend,
li,
menu,
nav,
ol,
p,
section,
td,
textarea,
th,
ul {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
font-size: 14px;
line-height: 1.5;
color: #313a6e;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
background-color: var(--primary-background);
}
a {
text-decoration: none;
}
button,
input,
select,
textarea {
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
img {
max-width: 100%;
}
[class*=icon] {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
vertical-align: -.125em;
speak: none;
font-variant: normal;
text-transform: none;
text-rendering: optimizeLegibility;
}
.icon-arrow-down:before {
content: "\e665";
}
.icon-close:before {
content: "\e646";
}
.icon-close-circle:before {
content: "\e66e";
}
.icon-search:before {
content: "\e600";
}
.icon-calculator:before {
content: "\e799";
}
.icon-user:before {
content: "\e7ae";
}
.icon-add:before {
content: "\e6df";
}
.icon-input:before {
content: "\e660";
}
.icon-loading:before {
content: "\e617";
}
.layout-center {
display: flex;
align-items: center;
justify-content: center;
}
.ant-btn {
&.btn-info {
background-color: var(--primary-color-2);
border-color: var(--primary-color-2);
color: #fff;
&:hover {
background-color: var(--primary-color-2-hover);
border-color: var(--primary-color-2-hover);
color: #fff;
}
}
}
.table {
table-layout: fixed;
border-collapse: collapse;
width: 100%;
th,td{
min-width: 0;
height: 42px;
-webkit-box-sizing: border-box;
box-sizing: border-box;
text-align: left;
text-overflow: ellipsis;
vertical-align: middle;
border-bottom: 1px solid #e8e8ec;
padding: 0 16px;
}
th {
white-space: nowrap;
overflow: hidden;
background-color: #f2f3f5;
position: relative;
height: 100%;
padding:10px 16px;
}
tr{
&:hover{
background-color: #ebf7ff;
}
}
}

View File

@ -12,13 +12,13 @@ export default defineConfig({
output: { output: {
manualChunks(id) { manualChunks(id) {
// console.log('chunk id',id) // console.log('chunk id',id)
if (id.includes('view-ui-plus')) { if (id.includes('ant-design')) {
return 'view-ui' return 'ui-libs'
} }
// if (id.includes('vue')) { // if (id.includes('vue')) {
// if (id.includes('node_modules')) {
// return 'vue' // return 'vue'
// } // }
// if (id.includes('node_modules')) {
// return id.toString().split('node_modules/')[1].split('/')[0].toString(); // return id.toString().split('node_modules/')[1].split('/')[0].toString();
// } // }
} }
@ -28,7 +28,7 @@ export default defineConfig({
base: './', base: './',
// resolve:{ // resolve:{
// alias:{ // alias:{
// '@': path.resolve(__dirname,"./src") // '@': path.resolve(__dirname,"./src")
// } // }
// }, // },
}) })

263
yarn.lock
View File

@ -2,11 +2,53 @@
# yarn lockfile v1 # 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.3.1"
resolved "https://registry.npmmirror.com/@ant-design/icons-svg/-/icons-svg-4.3.1.tgz#4b2f65a17d4d32b526baa6414aca2117382bf8da"
integrity sha512-4QBZg8ccyC6LPIRii7A0bZUk3+lEDCLnhB+FVsflGdcWPPmV+j3fire4AwwoqHV/BibgvBmR9ZIo4s867smv+g==
"@ant-design/icons-vue@^7.0.0":
version "7.0.1"
resolved "https://registry.npmmirror.com/@ant-design/icons-vue/-/icons-vue-7.0.1.tgz#83de301771fadd03f3890e627314102405c31c22"
integrity sha512-eCqY2unfZK6Fe02AwFlDHLfoyEFreP6rBwAZMIJ1LugmfMiVgwWDYlp1YsRugaPtICYOabV1iWxXdP12u9U43Q==
dependencies:
"@ant-design/colors" "^6.0.0"
"@ant-design/icons-svg" "^4.2.1"
"@babel/parser@^7.23.6": "@babel/parser@^7.23.6":
version "7.23.6" version "7.23.6"
resolved "https://registry.npmmirror.com/@babel/parser/-/parser-7.23.6.tgz" resolved "https://registry.npmmirror.com/@babel/parser/-/parser-7.23.6.tgz"
integrity sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ== integrity sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==
"@babel/runtime@^7.10.5":
version "7.23.8"
resolved "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.23.8.tgz#8ee6fe1ac47add7122902f257b8ddf55c898f650"
integrity sha512-Y7KbAP984rn1VGMbGqKmBLio9V7y5Je9GvU4rQPCPinCyNfUcToxIXl06d59URp/F3LwinvODxab5N/G6qggkw==
dependencies:
regenerator-runtime "^0.14.0"
"@ctrl/tinycolor@^3.4.0", "@ctrl/tinycolor@^3.5.0":
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==
"@emotion/hash@^0.9.0":
version "0.9.1"
resolved "https://registry.npmmirror.com/@emotion/hash/-/hash-0.9.1.tgz#4ffb0055f7ef676ebc3a5a91fb621393294e2f43"
integrity sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==
"@emotion/unitless@^0.8.0":
version "0.8.1"
resolved "https://registry.npmmirror.com/@emotion/unitless/-/unitless-0.8.1.tgz#182b5a4704ef8ad91bde93f7a860a88fd92c79a3"
integrity sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==
"@esbuild/android-arm64@0.18.20": "@esbuild/android-arm64@0.18.20":
version "0.18.20" version "0.18.20"
resolved "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz#984b4f9c8d0377443cc2dfcef266d02244593622" resolved "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz#984b4f9c8d0377443cc2dfcef266d02244593622"
@ -122,6 +164,14 @@
resolved "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz" resolved "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz"
integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==
"@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/node@^20.10.5": "@types/node@^20.10.5":
version "20.10.5" version "20.10.5"
resolved "https://registry.npmmirror.com/@types/node/-/node-20.10.5.tgz" resolved "https://registry.npmmirror.com/@types/node/-/node-20.10.5.tgz"
@ -255,6 +305,34 @@
resolved "https://registry.npmmirror.com/@vue/shared/-/shared-3.4.0.tgz" resolved "https://registry.npmmirror.com/@vue/shared/-/shared-3.4.0.tgz"
integrity sha512-Nhh3ed3G1R6HDAWiG6YYFt0Zmq/To6u5vjzwa9TIquGheCXPY6nEdIAO8ZdlwXsWqC2yNLj700FOvShpYt5CEA== integrity sha512-Nhh3ed3G1R6HDAWiG6YYFt0Zmq/To6u5vjzwa9TIquGheCXPY6nEdIAO8ZdlwXsWqC2yNLj700FOvShpYt5CEA==
ant-design-vue@4.x:
version "4.1.0"
resolved "https://registry.npmmirror.com/ant-design-vue/-/ant-design-vue-4.1.0.tgz#ec8d429cea7173775bc86ff083631897d5bdcdfb"
integrity sha512-sVQAfTCxpGRfFykM033/0ZWfNWbsL8EsqhBP9knbP4Ptc52zG57mQsCPWvq6Cj3yqmDJW6ykY05v0KB+5rAPXg==
dependencies:
"@ant-design/colors" "^6.0.0"
"@ant-design/icons-vue" "^7.0.0"
"@babel/runtime" "^7.10.5"
"@ctrl/tinycolor" "^3.5.0"
"@emotion/hash" "^0.9.0"
"@emotion/unitless" "^0.8.0"
"@simonwep/pickr" "~1.8.0"
array-tree-filter "^2.1.0"
async-validator "^4.0.0"
csstype "^3.1.1"
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"
stylis "^4.1.3"
throttle-debounce "^5.0.0"
vue-types "^3.0.0"
warning "^4.0.0"
anymatch@~3.1.2: anymatch@~3.1.2:
version "3.1.3" version "3.1.3"
resolved "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz" resolved "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz"
@ -263,21 +341,21 @@ anymatch@~3.1.2:
normalize-path "^3.0.0" normalize-path "^3.0.0"
picomatch "^2.0.4" picomatch "^2.0.4"
async-validator@^3.3.0: array-tree-filter@^2.1.0:
version "3.5.2" version "2.1.0"
resolved "https://registry.npmmirror.com/async-validator/-/async-validator-3.5.2.tgz" resolved "https://registry.npmmirror.com/array-tree-filter/-/array-tree-filter-2.1.0.tgz#873ac00fec83749f255ac8dd083814b4f6329190"
integrity sha512-8eLCg00W9pIRZSB781UUX/H6Oskmm8xloZfr09lz5bikRpBVDlJ3hRVuxxP1SxcwsEYfJ4IU8Q19Y8/893r3rQ== integrity sha512-4ROwICNlNw/Hqa9v+rk5h22KjmzB1JGTMVKP2AKJBOCgb0yL0ASf0+YvCcLNNwquOHNX48jkeZIJ3a+oOQqKcw==
async-validator@^4.0.0:
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==
balanced-match@^1.0.0: balanced-match@^1.0.0:
version "1.0.2" version "1.0.2"
resolved "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz" resolved "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
batch-processor@1.0.0:
version "1.0.0"
resolved "https://registry.npmmirror.com/batch-processor/-/batch-processor-1.0.0.tgz"
integrity sha512-xoLQD8gmmR32MeuBHgH0Tzd5PuSZx71ZsbhVxOCRbgktZEPe4SQy7s9Z50uPp0F/f7iw2XmkHN2xkgbMfckMDA==
binary-extensions@^2.0.0: binary-extensions@^2.0.0:
version "2.2.0" version "2.2.0"
resolved "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.2.0.tgz" resolved "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.2.0.tgz"
@ -312,27 +390,27 @@ braces@~3.0.2:
optionalDependencies: optionalDependencies:
fsevents "~2.3.2" fsevents "~2.3.2"
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==
computeds@^0.0.1: computeds@^0.0.1:
version "0.0.1" version "0.0.1"
resolved "https://registry.npmmirror.com/computeds/-/computeds-0.0.1.tgz" resolved "https://registry.npmmirror.com/computeds/-/computeds-0.0.1.tgz"
integrity sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q== integrity sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==
countup.js@^1.9.3: core-js@^3.15.1:
version "1.9.3" version "3.35.0"
resolved "https://registry.npmmirror.com/countup.js/-/countup.js-1.9.3.tgz" resolved "https://registry.npmmirror.com/core-js/-/core-js-3.35.0.tgz#58e651688484f83c34196ca13f099574ee53d6b4"
integrity sha512-UHf2P/mFKaESqdPq+UdBJm/1y8lYdlcDd0nTZHNC8cxWoJwZr1Eldm1PpWui446vDl5Pd8PtRYkr3q6K4+Qa5A== integrity sha512-ntakECeqg81KqMueeGJ79Q5ZgQNR+6eaE8sxGCx62zMbAIj65q+uYvatToew3m6eAGdU4gNZwpZ34NMe4GYswg==
csstype@^3.1.3: csstype@^3.1.1, csstype@^3.1.3:
version "3.1.3" version "3.1.3"
resolved "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz" resolved "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz"
integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==
dayjs@^1.11.0: dayjs@^1.10.5, dayjs@^1.11.10:
version "1.11.10"
resolved "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.10.tgz"
integrity sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==
dayjs@^1.11.10:
version "1.11.10" version "1.11.10"
resolved "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.10.tgz#68acea85317a6e164457d6d6947564029a6a16a0" resolved "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.10.tgz#68acea85317a6e164457d6d6947564029a6a16a0"
integrity sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ== integrity sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==
@ -342,17 +420,15 @@ de-indent@^1.0.2:
resolved "https://registry.npmmirror.com/de-indent/-/de-indent-1.0.2.tgz" resolved "https://registry.npmmirror.com/de-indent/-/de-indent-1.0.2.tgz"
integrity sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg== integrity sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==
deepmerge@^2.2.1: dom-align@^1.12.1:
version "2.2.1" version "1.12.4"
resolved "https://registry.npmmirror.com/deepmerge/-/deepmerge-2.2.1.tgz" resolved "https://registry.npmmirror.com/dom-align/-/dom-align-1.12.4.tgz#3503992eb2a7cfcb2ed3b2a6d21e0b9c00d54511"
integrity sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA== integrity sha512-R8LUSEay/68zE5c8/3BDxiTEvgb4xZTF0RKmAHfiEVN3klfIpXfi2/QCoiWPccVQ0J/ZGdz9OjzL4uJEP/MRAw==
element-resize-detector@^1.2.0: dom-scroll-into-view@^2.0.0:
version "1.2.4" version "2.0.1"
resolved "https://registry.npmmirror.com/element-resize-detector/-/element-resize-detector-1.2.4.tgz" resolved "https://registry.npmmirror.com/dom-scroll-into-view/-/dom-scroll-into-view-2.0.1.tgz#0decc8522801fd8d3f1c6ba355a74d382c5f989b"
integrity sha512-Fl5Ftk6WwXE0wqCgNoseKWndjzZlDCwuPTcoVZfCP9R3EHQF8qUtr3YUPNETegRBOKqQKPW3n4kiIWngGi8tKg== integrity sha512-bvVTQe1lfaUr1oFzZX80ce9KLDlZ3iU+XGNE/bz9HnGdklTieqsbmsLHe+rT2XWqopvL0PckkYqN7ksmm5pe3w==
dependencies:
batch-processor "1.0.0"
entities@^4.5.0: entities@^4.5.0:
version "4.5.0" version "4.5.0"
@ -445,20 +521,32 @@ is-number@^7.0.0:
resolved "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz" resolved "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz"
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
js-calendar@^1.2.3: is-plain-object@3.0.1:
version "1.2.3" version "3.0.1"
resolved "https://registry.npmmirror.com/js-calendar/-/js-calendar-1.2.3.tgz" resolved "https://registry.npmmirror.com/is-plain-object/-/is-plain-object-3.0.1.tgz#662d92d24c0aa4302407b0d45d21f2251c85f85b"
integrity sha512-dAA1/Zbp4+c5E+ARCVTIuKepXsNLzSYfzvOimiYD4S5eeP9QuplSHLcdhfqFSwyM1o1u6ku6RRRCyaZ0YAjiBw== integrity sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==
lodash.chunk@^4.2.0: "js-tokens@^3.0.0 || ^4.0.0":
version "4.2.0" version "4.0.0"
resolved "https://registry.npmmirror.com/lodash.chunk/-/lodash.chunk-4.2.0.tgz" resolved "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
integrity sha512-ZzydJKfUHJwHa+hF5X66zLFCBrWn5GeF28OHEr4WVWtNDXlQ/IjWKPBiikqKo2ne0+v6JgCgJ0GzJp8k8bHC7w== integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
lodash.throttle@^4.1.1: lodash-es@^4.17.15:
version "4.1.1" version "4.17.21"
resolved "https://registry.npmmirror.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz" resolved "https://registry.npmmirror.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee"
integrity sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ== integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==
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"
lru-cache@^6.0.0: lru-cache@^6.0.0:
version "6.0.0" version "6.0.0"
@ -491,16 +579,16 @@ nanoid@^3.3.7:
resolved "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.7.tgz" resolved "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.7.tgz"
integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==
nanopop@^2.1.0:
version "2.3.0"
resolved "https://registry.npmmirror.com/nanopop/-/nanopop-2.3.0.tgz#a5f672fba27d45d6ecbd0b59789c040072915123"
integrity sha512-fzN+T2K7/Ah25XU02MJkPZ5q4Tj5FpjmIYq4rvoHX4yb16HzFdCO6JxFFn5Y/oBhQ8no8fUZavnyIv9/+xkBBw==
normalize-path@^3.0.0, normalize-path@~3.0.0: normalize-path@^3.0.0, normalize-path@~3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz" resolved "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz"
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
numeral@^2.0.6:
version "2.0.6"
resolved "https://registry.npmmirror.com/numeral/-/numeral-2.0.6.tgz"
integrity sha512-qaKRmtYPZ5qdw4jWJD6bxEf1FJEqllJrwxCLIm0sQU/A7v2/czigzOb+C2uSiFsa9lBUzeH7M1oK+Q+OLxL3kA==
path-browserify@^1.0.1: path-browserify@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.npmmirror.com/path-browserify/-/path-browserify-1.0.1.tgz" resolved "https://registry.npmmirror.com/path-browserify/-/path-browserify-1.0.1.tgz"
@ -524,11 +612,6 @@ pinia@^2.1.7:
"@vue/devtools-api" "^6.5.0" "@vue/devtools-api" "^6.5.0"
vue-demi ">=0.14.5" vue-demi ">=0.14.5"
popper.js@^1.14.6:
version "1.16.1"
resolved "https://registry.npmmirror.com/popper.js/-/popper.js-1.16.1.tgz"
integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==
postcss@^8.4.27, postcss@^8.4.32: postcss@^8.4.27, postcss@^8.4.32:
version "8.4.32" version "8.4.32"
resolved "https://registry.npmmirror.com/postcss/-/postcss-8.4.32.tgz" resolved "https://registry.npmmirror.com/postcss/-/postcss-8.4.32.tgz"
@ -545,6 +628,16 @@ readdirp@~3.6.0:
dependencies: dependencies:
picomatch "^2.2.1" picomatch "^2.2.1"
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@^3.27.1: rollup@^3.27.1:
version "3.29.4" version "3.29.4"
resolved "https://registry.npmmirror.com/rollup/-/rollup-3.29.4.tgz" resolved "https://registry.npmmirror.com/rollup/-/rollup-3.29.4.tgz"
@ -561,10 +654,12 @@ sass@^1.69.5:
immutable "^4.0.0" immutable "^4.0.0"
source-map-js ">=0.6.2 <2.0.0" source-map-js ">=0.6.2 <2.0.0"
select@^1.1.2: scroll-into-view-if-needed@^2.2.25:
version "1.1.2" version "2.2.31"
resolved "https://registry.npmmirror.com/select/-/select-1.1.2.tgz" resolved "https://registry.npmmirror.com/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.31.tgz#d3c482959dc483e37962d1521254e3295d0d1587"
integrity sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA== integrity sha512-dGCXy99wZQivjmjIqihaBQNjryrz5rueJY7eHfTdyWEiR4ttYpsajb14rn9s5d4DY4EcY6+4+U/maARBXJedkA==
dependencies:
compute-scroll-into-view "^1.0.20"
semver@^7.5.4: semver@^7.5.4:
version "7.5.4" version "7.5.4"
@ -573,15 +668,25 @@ semver@^7.5.4:
dependencies: dependencies:
lru-cache "^6.0.0" lru-cache "^6.0.0"
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@>=0.6.2 <2.0.0", source-map-js@^1.0.2: "source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.2:
version "1.0.2" version "1.0.2"
resolved "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.0.2.tgz" resolved "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.0.2.tgz"
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
tinycolor2@^1.4.1: stylis@^4.1.3:
version "1.6.0" version "4.3.1"
resolved "https://registry.npmmirror.com/tinycolor2/-/tinycolor2-1.6.0.tgz" resolved "https://registry.npmmirror.com/stylis/-/stylis-4.3.1.tgz#ed8a9ebf9f76fe1e12d462f5cc3c4c980b23a7eb"
integrity sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw== integrity sha512-EQepAV+wMsIaGVGX1RECzgrcqRRU/0sYOHkeLsZ3fzHaHXZy4DaOOX0vOlGQdlsjkh3mFHAIlVimpwAs4dslyQ==
throttle-debounce@^5.0.0:
version "5.0.0"
resolved "https://registry.npmmirror.com/throttle-debounce/-/throttle-debounce-5.0.0.tgz#a17a4039e82a2ed38a5e7268e4132d6960d41933"
integrity sha512-2iQTSgkkc1Zyk0MeVrt/3BvuOXYPl/R8Z0U2xxo9rjwNciaHDG3R+Lm6dh4EeUci49DanvBnuqI6jshoQQRGEg==
to-regex-range@^5.0.1: to-regex-range@^5.0.1:
version "5.0.1" version "5.0.1"
@ -600,30 +705,6 @@ undici-types@~5.26.4:
resolved "https://registry.npmmirror.com/undici-types/-/undici-types-5.26.5.tgz" resolved "https://registry.npmmirror.com/undici-types/-/undici-types-5.26.5.tgz"
integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==
v-click-outside-x@^3.7.1:
version "3.7.1"
resolved "https://registry.npmmirror.com/v-click-outside-x/-/v-click-outside-x-3.7.1.tgz"
integrity sha512-WmUgmcIXr9clVpm1AYS/FgHtcDicfnfoxgQCNg4O6vfk9GVnxA0vSqO321ogUo0b7czYTidj7fQENvWFMWOkUg==
view-ui-plus@^1.3.15:
version "1.3.15"
resolved "https://registry.npmmirror.com/view-ui-plus/-/view-ui-plus-1.3.15.tgz"
integrity sha512-dbi3uTk8twgtpino0QFIvCb3Gck135czbnvxs2M0lOmUQMKAK7GqJ3m8IobwyWXAxkoA1+Ek8QMeC3a+InOWpQ==
dependencies:
async-validator "^3.3.0"
countup.js "^1.9.3"
dayjs "^1.11.0"
deepmerge "^2.2.1"
element-resize-detector "^1.2.0"
js-calendar "^1.2.3"
lodash.chunk "^4.2.0"
lodash.throttle "^4.1.1"
numeral "^2.0.6"
popper.js "^1.14.6"
select "^1.1.2"
tinycolor2 "^1.4.1"
v-click-outside-x "^3.7.1"
vite@^4.3.2: vite@^4.3.2:
version "4.5.1" version "4.5.1"
resolved "https://registry.npmmirror.com/vite/-/vite-4.5.1.tgz" resolved "https://registry.npmmirror.com/vite/-/vite-4.5.1.tgz"
@ -664,6 +745,13 @@ vue-tsc@^1.4.2:
"@vue/language-core" "1.8.27" "@vue/language-core" "1.8.27"
semver "^7.5.4" semver "^7.5.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.0: vue@^3.4.0:
version "3.4.0" version "3.4.0"
resolved "https://registry.npmmirror.com/vue/-/vue-3.4.0.tgz" resolved "https://registry.npmmirror.com/vue/-/vue-3.4.0.tgz"
@ -675,6 +763,13 @@ vue@^3.4.0:
"@vue/server-renderer" "3.4.0" "@vue/server-renderer" "3.4.0"
"@vue/shared" "3.4.0" "@vue/shared" "3.4.0"
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"
yallist@^4.0.0: yallist@^4.0.0:
version "4.0.0" version "4.0.0"
resolved "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz" resolved "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz"