Initial commit: One Pipe System

完整的管理系统,包含账户管理、卡片管理、套餐管理、财务管理等功能模块。

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
sexygoat
2026-01-22 16:35:33 +08:00
commit 222e5bb11a
495 changed files with 145440 additions and 0 deletions

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 954 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 726 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 944 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 810 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
src/assets/img/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 514 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 409 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 439 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 292 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 286 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 293 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 448 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 416 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 509 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
src/assets/img/user/bg.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

196
src/assets/styles/app.scss Normal file
View File

@@ -0,0 +1,196 @@
// 全局样式
@font-face {
font-family: 'DMSans';
font-style: normal;
font-weight: 400;
src: url(../fonts/DMSans.woff2) format('woff2');
}
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 400;
src: url(../fonts/Montserrat.woff2) format('woff2');
}
.btn-icon {
font-size: 10px;
}
.el-btn-red {
color: #fa6962 !important;
&:hover {
opacity: 0.9;
}
&:active {
opacity: 0.7;
}
}
// 顶部进度条颜色
#nprogress .bar {
background-color: color-mix(in srgb, var(--main-color) 65%, white);
}
// 处理移动端组件兼容性
@media screen and (max-width: $device-phone) {
* {
cursor: default !important;
}
.el-col2 {
margin-top: 15px;
}
}
// 背景滤镜
*,
::before,
::after {
--tw-backdrop-blur: ;
--tw-backdrop-brightness: ;
--tw-backdrop-contrast: ;
--tw-backdrop-grayscale: ;
--tw-backdrop-hue-rotate: ;
--tw-backdrop-invert: ;
--tw-backdrop-opacity: ;
--tw-backdrop-saturate: ;
--tw-backdrop-sepia: ;
}
// 色弱模式
.color-weak {
filter: invert(80%);
-webkit-filter: invert(80%);
}
#noop {
display: none;
}
// 语言切换选中样式
.langDropDownStyle {
// 选中项背景颜色
.is-selected {
background-color: rgba(var(--art-gray-200-rgb), 0.8) !important;
}
// 语言切换按钮菜单样式优化
.lang-btn-item {
.el-dropdown-menu__item {
padding-left: 13px !important;
padding-right: 6px !important;
margin-bottom: 3px !important;
}
&:last-child {
.el-dropdown-menu__item {
margin-bottom: 0 !important;
}
}
.menu-txt {
min-width: 60px;
display: block;
}
i {
font-size: 10px;
margin-left: 10px;
}
}
}
// 盒子默认边框
.page-content,
.art-custom-card {
border: 1px solid var(--art-card-border) !important;
}
// 盒子边框
[data-box-mode='border-mode'] {
.page-content,
.art-custom-card,
.art-table-card {
border: 1px solid var(--art-card-border) !important;
}
.layout-sidebar {
border-right: 1px solid var(--art-card-border) !important;
}
}
// 盒子阴影
[data-box-mode='shadow-mode'] {
.page-content,
.art-custom-card,
.art-table-card {
box-shadow: 0px 0px 4px 0px rgba(0, 0, 0, 0.04) !important;
border: 1px solid rgba(var(--art-gray-300-rgb), 0.3) !important;
}
.layout-sidebar {
border-right: 1px solid rgba(var(--art-gray-300-rgb), 0.4) !important;
}
}
html,
body {
touch-action: none; /* 禁用触摸事件 */
overflow-x: hidden; /* 禁用横向滚动 */
}
// 元素全屏
.el-full-screen {
position: fixed;
top: 0;
left: 0;
right: 0;
width: 100vw !important;
height: 100vh !important;
z-index: 500;
margin-top: 0;
padding: 15px;
box-sizing: border-box;
background-color: var(--art-main-bg-color);
.art-table-full-screen {
height: 100% !important;
}
}
// 表格卡片
.art-table-card {
flex: 1;
display: flex;
flex-direction: column;
margin-top: 15px;
border-radius: calc(var(--custom-radius) / 2 + 2px) !important;
.el-card__body {
height: 100%;
overflow: auto;
}
}
.flex-row-sb {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
.mt-20 {
margin-top: 20px;
}
.flex-row-g20 {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
gap: 20px;
}

View File

@@ -0,0 +1,11 @@
// 主题切换过渡优化,去除不适感
.theme-change {
* {
transition: 0s !important;
}
.el-switch__core,
.el-switch__action {
transition: all 0.3s !important;
}
}

215
src/assets/styles/dark.scss Normal file
View File

@@ -0,0 +1,215 @@
/*
* 深色主题
* 单页面移除深色主题 document.getElementsByTagName("html")[0].removeAttribute('class')
*/
$font-color: rgba(#ffffff, 0.7);
$background-color: #070707;
/* 覆盖element-plus默认深色背景色 */
html.dark {
// ✅ element-plus
// --el-bg-color: $background-color;
--el-text-color-regular: $font-color;
// ✅ 富文本编辑器
// 工具栏背景颜色
--w-e-toolbar-bg-color: var(--art-main-bg-color);
// 输入区域背景颜色
--w-e-textarea-bg-color: var(--art-main-bg-color);
// 工具栏文字颜色
--w-e-toolbar-color: var(--art-text-gray-600);
// 选中菜单颜色
--w-e-toolbar-active-bg-color: rgba(var(--art-gray-100-rgb), 0.8);
// 弹窗边框颜色
--w-e-toolbar-border-color: var(--art-border-dashed-color);
// 分割线颜色
--w-e-textarea-border-color: var(--art-border-dashed-color);
// 链接输入框边框颜色
--w-e-modal-button-border-color: var(--art-border-dashed-color);
// 表格头颜色
--w-e-textarea-slight-bg-color: var(--art-color);
// 按钮背景颜色
--w-e-modal-button-bg-color: var(--art-color);
}
.dark {
color: $font-color !important;
background: $background-color !important;
/* 全局文字颜色 */
body {
color: $font-color;
h1,
h2,
h3,
h4,
h5,
h6,
.lang .btn,
.layout-top-bar .user .name,
.dark-text {
color: $font-color !important;
}
}
// 图片降低亮度
img {
filter: brightness(0.92) saturate(1.25);
}
.editor-wrapper {
*:not(pre code *) {
color: inherit !important;
}
}
.img-cutter {
*:not([class^='el-']) {
color: inherit !important;
}
}
// ✅ 左侧菜单样式
.layout-sidebar,
.dual-menu {
.el-menu-dark {
// 选中颜色
.el-menu-item.is-active {
background: transparent;
}
.el-sub-menu__title {
.el-icon {
color: var(--art-gray-800) !important;
}
}
// 鼠标移入背景色
.el-sub-menu__title:hover,
.el-menu-item:not(.is-active):hover {
background: rgba(var(--art-gray-200-rgb), 0.6) !important;
}
[level-item='2'].is-active:not(.el-menu--collapse) {
&.is-active {
&:before {
margin-left: -10px !important;
}
}
}
.el-menu:not(.el-menu--collapse) {
// 选中颜色
.el-menu-item.is-active {
&:before {
content: '';
width: 5px;
height: 5px;
border-radius: 50%;
position: absolute;
top: 0;
bottom: 0;
margin: auto;
background: var(--main-color) !important;
transition: all 0.2s;
margin-left: -18px;
}
}
}
}
}
.page-content .article-list .item .left .outer > div {
border-right-color: var(--dark-border-color) !important;
}
// ✅ 富文本编辑器
// 分隔线
.w-e-bar-divider {
background-color: var(--art-gray-300) !important;
}
// 下拉选择框
.w-e-select-list {
background-color: var(--art-main-bg-color) !important;
border: 1px solid var(--art-border-dashed-color) !important;
}
/* 弹出框 */
.w-e-drop-panel {
border: 1px solid var(--art-border-dashed-color) !important;
}
/* 工具栏菜单 */
.w-e-bar-item-group .w-e-bar-item-menus-container {
background-color: var(--art-main-bg-color) !important;
border: 1px solid var(--art-border-dashed-color) !important;
}
/* 下拉选择框 hover 样式调整 */
.w-e-select-list ul li:hover,
/* 工具栏 hover 按钮背景颜色 */
.w-e-bar-item button:hover {
background-color: var(--art-color) !important;
}
/* 代码块 */
.w-e-text-container [data-slate-editor] pre > code {
background-color: var(--art-gray-100) !important;
border: 1px solid var(--art-border-dashed-color) !important;
text-shadow: none !important;
}
/* 引用 */
.w-e-text-container [data-slate-editor] blockquote {
border-left: 4px solid var(--art-gray-200) !important;
background-color: var(--art-color);
}
.editor-wrapper {
.w-e-text-container [data-slate-editor] .table-container th:last-of-type {
border-right: 1px solid var(--art-gray-200) !important;
}
.w-e-modal {
background-color: var(--art-color);
}
}
// 工作台标签文字颜色
.worktab .scroll-view .tabs li {
color: var(--art-text-gray-800) !important;
}
// 顶部按钮文字颜色
.layout-top-bar .btn-box .btn i,
.fast-enter-trigger .btn i {
color: var(--art-text-gray-700) !important;
}
}
// 移动端文字颜色
@media screen and (max-width: $device-phone) {
.dark {
$font-color: rgba(#ffffff, 0.8);
--el-text-color-regular: $font-color !important;
color: $font-color !important;
body {
color: $font-color !important;
h1,
h2,
h3,
h4,
h5,
h6,
.lang .btn,
.layout-top-bar .user .name {
color: $font-color !important;
}
}
}
}

View File

@@ -0,0 +1,16 @@
// 自定义Element 暗黑主题
@forward 'element-plus/theme-chalk/src/dark/var.scss' //
with (
$colors: (
//
'white': #ffffff,
'black': #000000,
'success': ('base': #13deb9),
'warning': ('base': #ffae1f),
'danger': ('base': #ff4d4f),
'error': ('base': #fa896b)
)
);
@use 'element-plus/theme-chalk/src/dark/css-vars.scss' as *;

View File

@@ -0,0 +1,34 @@
// https://github.com/element-plus/element-plus/blob/dev/packages/theme-chalk/src/common/var.scss
// 自定义Element 亮色主题
@forward 'element-plus/theme-chalk/src/common/var.scss' //
with (
//
$colors: (
//
'white': #ffffff,
'black': #000000,
'success': ('base': #13deb9),
'warning': ('base': #ffae1f),
'danger': ('base': #ff4d4f),
'error': ('base': #fa896b)
),
$button: (
//
'hover-bg-color': var(--el-color-primary-light-9),
'hover-border-color': var(--el-color-primary),
'border-color': var(--el-color-primary),
'text-color': var(--el-color-primary)
),
$messagebox: (
//
'border-radius': '12px'
),
$popover: (
//
'padding': '14px',
'border-radius': '10px'
)
);
@use 'element-plus/theme-chalk/src/index.scss' as *;

View File

@@ -0,0 +1,402 @@
// 优化 Element Plus 组件库默认样式
:root {
// 系统主色
--main-color: var(--el-color-primary);
--el-color-white: white !important;
--el-color-black: white !important;
// 输入框边框颜色
// --el-border-color: #E4E4E7 !important; // DCDFE6
// 按钮粗度
--el-font-weight-primary: 400 !important;
--el-component-custom-height: 36px !important;
--el-component-size: var(--el-component-custom-height) !important;
// 边框、按钮圆角...
--el-border-radius-base: calc(var(--custom-radius) / 3 + 2px) !important;
--el-border-radius-small: 10px !important;
--el-messagebox-border-radius: 10px !important;
.region .el-radio-button__original-radio:checked + .el-radio-button__inner {
color: var(--main-color);
}
}
// 优化菜单折叠展开动画(提升动画流畅度)
.el-menu.el-menu--inline {
transition: max-height 0.26s cubic-bezier(0.4, 0, 0.2, 1) !important;
}
// 优化菜单 item hover 动画(提升鼠标跟手感)
.el-sub-menu__title,
.el-menu-item {
transition: background-color 0s !important;
}
// -------------------------------- 修改 el-size=default 组件默认高度 start --------------------------------
// 修改 el-button 高度
.el-button--default {
height: var(--el-component-custom-height) !important;
}
// 修改 el-select 高度
.el-select--default {
.el-select__wrapper {
min-height: var(--el-component-custom-height) !important;
}
}
// 修改 el-checkbox-button 高度
.el-checkbox-button--default .el-checkbox-button__inner,
// 修改 el-radio-button 高度
.el-radio-button--default .el-radio-button__inner {
padding: 10px 15px !important;
}
// -------------------------------- 修改 el-size=default 组件默认高度 end --------------------------------
.el-pagination.is-background .btn-next,
.el-pagination.is-background .btn-prev,
.el-pagination.is-background .el-pager li {
border-radius: 6px;
}
.el-popover {
min-width: 80px;
}
.el-dialog {
border-radius: 100px !important;
border-radius: calc(var(--custom-radius) / 1.2 + 2px) !important;
overflow: hidden;
}
.el-dialog__header {
.el-dialog__title {
font-size: 16px;
}
}
.el-dialog__body {
padding: 25px 0 !important;
position: relative; // 为了兼容 el-pagination 样式,需要设置 relative不然会影响 el-pagination 的样式,比如 el-pagination__jump--small 会被影响,导致 el-pagination__jump--small 按钮无法点击,详见 URL_ADDRESS.com/element-plus/element-plus/issues/5684#issuecomment-1176299275;
}
.el-dialog.el-dialog-border {
.el-dialog__body {
// 上边框
&::before,
// 下边框
&::after {
content: '';
position: absolute;
left: -16px;
width: calc(100% + 32px);
height: 1px;
background-color: rgba(var(--art-gray-300-rgb), 0.56);
}
&::before {
top: 0;
}
&::after {
bottom: 0;
}
}
}
// ✅ el-message 样式优化
.el-message {
background-color: var(--art-main-bg-color) !important;
border: 0 !important;
box-shadow:
0 6px 16px 0 rgba(0, 0, 0, 0.08),
0 3px 6px -4px rgba(0, 0, 0, 0.12),
0 9px 28px 8px rgba(0, 0, 0, 0.05) !important;
p {
color: #515a6e !important;
font-size: 13px;
}
}
// 修改 el-dropdown 样式
.el-dropdown-menu {
padding: 6px !important;
border-radius: 10px !important;
border: none !important;
.el-dropdown-menu__item {
padding: 6px 16px !important;
border-radius: 6px !important;
&:hover:not(.is-disabled) {
color: var(--art-gray-900) !important;
background-color: var(--art-gray-200) !important;
}
}
}
// 隐藏 select、dropdown 的三角
.el-select__popper,
.el-dropdown__popper {
margin-top: -6px !important;
.el-popper__arrow {
display: none;
}
}
.el-dropdown-selfdefine:focus {
outline: none !important;
}
// 处理移动端组件兼容性
@media screen and (max-width: $device-phone) {
.el-message-box,
.el-message,
.el-dialog {
width: calc(100% - 24px) !important;
}
.el-date-picker.has-sidebar.has-time {
width: calc(100% - 24px);
left: 12px !important;
}
.el-picker-panel *[slot='sidebar'],
.el-picker-panel__sidebar {
display: none;
}
.el-picker-panel *[slot='sidebar'] + .el-picker-panel__body,
.el-picker-panel__sidebar + .el-picker-panel__body {
margin-left: 0;
}
}
// 修改el-button样式
.el-button {
&.el-button--text {
background-color: transparent !important;
padding: 0 !important;
span {
margin-left: 0 !important;
}
}
}
// 修改el-tag样式
.el-tag {
height: 26px !important;
line-height: 26px !important;
border: 0 !important;
border-radius: 6px !important;
font-weight: bold;
transition: all 0s !important;
}
.el-checkbox-group {
&.el-table-filter__checkbox-group label.el-checkbox {
height: 17px !important;
.el-checkbox__label {
font-weight: 400 !important;
}
}
}
.el-checkbox {
.el-checkbox__inner {
width: 18px !important;
height: 18px !important;
border-radius: 4px !important;
&::before {
content: '';
height: 3px !important;
top: 6px !important;
background-color: #fff !important;
transform: scale(0.6) !important;
}
&::after {
width: 4px;
height: 8px;
left: 0;
right: 0;
top: 0;
bottom: 4px;
margin: auto;
border: 2px solid var(--el-checkbox-checked-icon-color);
border-left: 0;
border-top: 0;
}
}
}
.el-notification .el-notification__icon {
font-size: 22px !important;
}
// 修改 el-message-box 样式
.el-message-box__headerbtn .el-message-box__close,
.el-dialog__headerbtn .el-dialog__close {
color: var(--art-gray-500) !important;
top: 7px !important;
right: 7px !important;
padding: 7px !important;
border-radius: 5px !important;
transition: all 0.3s !important;
&:hover {
background-color: var(--art-gray-200) !important;
color: var(--art-gray-800) !important;
}
}
.el-message-box {
padding: 25px 20px !important;
}
.el-message-box__title {
font-weight: 500 !important;
}
.el-table__column-filter-trigger i {
color: var(--main-color) !important;
margin: -3px 0 0 2px;
}
// 去除 el-dropdown 鼠标放上去出现的边框
.el-tooltip__trigger:focus-visible {
outline: unset;
}
// ipad 表单右侧按钮优化
@media screen and (max-width: $device-ipad-pro) {
.el-table-fixed-column--right {
padding-right: 0 !important;
.el-button {
margin: 5px 10px 5px 0 !important;
}
}
}
.login-out-dialog {
padding: 30px 20px !important;
border-radius: 10px !important;
}
// 修改 dialog 动画
.dialog-fade-enter-active {
.el-dialog {
animation: dialog-open 0.3s cubic-bezier(0.32, 0.14, 0.15, 0.86);
// 修复 el-dialog 动画后宽度不自适应问题
.el-select__selected-item {
display: inline-block;
}
}
}
.dialog-fade-leave-active {
animation: fade-out 0.2s linear;
.el-dialog {
animation: dialog-close 0.2s cubic-bezier(0.78, 0.14, 0.15, 0.86);
}
}
@keyframes dialog-open {
0% {
opacity: 0;
transform: scale(0.2);
}
100% {
opacity: 1;
transform: scale(1);
}
}
@keyframes dialog-close {
0% {
opacity: 1;
transform: scale(1);
}
100% {
opacity: 0;
transform: scale(0.2);
}
}
// 遮罩层动画
@keyframes fade-out {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
// 修改 el-select 样式
.el-select__popper:not(.el-tree-select__popper) {
.el-select-dropdown__list {
padding: 5px !important;
.el-select-dropdown__item {
height: 34px !important;
line-height: 34px !important;
border-radius: 6px !important;
&.is-selected {
color: var(--art-gray-900) !important;
font-weight: 400 !important;
background-color: var(--art-gray-200) !important;
margin-bottom: 4px !important;
}
&:hover {
background-color: var(--art-gray-200) !important;
}
}
.el-select-dropdown__item:hover ~ .is-selected,
.el-select-dropdown__item.is-selected:has(~ .el-select-dropdown__item:hover) {
background-color: transparent !important;
}
}
}
// 修改 el-tree-select 样式
.el-tree-select__popper {
.el-select-dropdown__list {
padding: 5px !important;
.el-tree-node {
.el-tree-node__content {
height: 36px !important;
border-radius: 6px !important;
&:hover {
background-color: var(--art-gray-200) !important;
}
}
}
}
}
// 实现水波纹在文字下面效果
.el-button > span {
position: relative;
z-index: 10;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,157 @@
// sass 混合宏(函数)
/**
* 溢出省略号
* @param {Number} 行数
*/
@mixin ellipsis($rowCount: 1) {
@if $rowCount <=1 {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
} @else {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: $rowCount;
-webkit-box-orient: vertical;
}
}
/**
* 控制用户能否选中文本
* @param {String} 类型
*/
@mixin userSelect($value: none) {
user-select: $value;
-moz-user-select: $value;
-ms-user-select: $value;
-webkit-user-select: $value;
}
// 绝对定位居中
@mixin absoluteCenter() {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
}
/**
* css3动画
*
*/
@mixin animation(
$from: (
width: 0px
),
$to: (
width: 100px
),
$name: mymove,
$animate: mymove 2s 1 linear infinite
) {
-webkit-animation: $animate;
-o-animation: $animate;
animation: $animate;
@keyframes #{$name} {
from {
@each $key, $value in $from {
#{$key}: #{$value};
}
}
to {
@each $key, $value in $to {
#{$key}: #{$value};
}
}
}
@-webkit-keyframes #{$name} {
from {
@each $key, $value in $from {
$key: $value;
}
}
to {
@each $key, $value in $to {
$key: $value;
}
}
}
}
// 圆形盒子
@mixin circle($size: 11px, $bg: #fff) {
border-radius: 50%;
width: $size;
height: $size;
line-height: $size;
text-align: center;
background: $bg;
}
// placeholder
@mixin placeholder($color: #bbb) {
// Firefox
&::-moz-placeholder {
color: $color;
opacity: 1;
}
// Internet Explorer 10+
&:-ms-input-placeholder {
color: $color;
}
// Safari and Chrome
&::-webkit-input-placeholder {
color: $color;
}
&:placeholder-shown {
text-overflow: ellipsis;
}
}
//背景透明文字不透明。兼容IE8
@mixin betterTransparentize($color, $alpha) {
$c: rgba($color, $alpha);
$ie_c: ie_hex_str($c);
background: rgba($color, 1);
background: $c;
background: transparent \9;
zoom: 1;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#{$ie_c}, endColorstr=#{$ie_c});
-ms-filter: 'progid:DXImageTransform.Microsoft.gradient(startColorstr=#{$ie_c}, endColorstr=#{$ie_c})';
}
//添加浏览器前缀
@mixin browserPrefix($propertyName, $value) {
@each $prefix in -webkit-, -moz-, -ms-, -o-, '' {
#{$prefix}#{$propertyName}: $value;
}
}
// 边框
@mixin border($color: red) {
border: 1px solid $color;
}
// 背景滤镜
@mixin backdropBlur() {
--tw-backdrop-blur: blur(30px);
-webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness)
var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate)
var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate)
var(--tw-backdrop-sepia);
backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast)
var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert)
var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);
}

View File

@@ -0,0 +1,8 @@
// 移动端样式处理
// 去除移动端点击背景色
@media screen and (max-width: $device-ipad-pro) {
* {
-webkit-tap-highlight-color: transparent;
}
}

View File

@@ -0,0 +1,117 @@
/*
Atom One Dark by Daniel Gamage
Original One Dark Syntax theme from https://github.com/atom/one-dark-syntax
base: #282c34
mono-1: #abb2bf
mono-2: #818896
mono-3: #5c6370
hue-1: #56b6c2
hue-2: #61aeee
hue-3: #c678dd
hue-4: #98c379
hue-5: #e06c75
hue-5-2: #be5046
hue-6: #d19a66
hue-6-2: #e6c07b
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
// color: #abb2bf;
// background: #282c34;
color: #a6accd;
}
.hljs-string,
.hljs-section,
.hljs-selector-class,
.hljs-template-variable,
.hljs-deletion {
color: #aed07e !important;
}
.hljs-comment,
.hljs-quote {
color: #6f747d;
}
.hljs-doctag,
.hljs-keyword,
.hljs-formula {
color: #c792ea;
}
.hljs-section,
.hljs-name,
.hljs-selector-tag,
.hljs-deletion,
.hljs-subst {
color: #c86068;
}
.hljs-literal {
color: #56b6c2;
}
.hljs-string,
.hljs-regexp,
.hljs-addition,
.hljs-attribute,
.hljs-meta-string {
color: #abb2bf;
}
.hljs-attribute {
color: #c792ea;
}
.hljs-function {
color: #c792ea;
}
.hljs-type {
color: #f07178;
}
.hljs-title {
color: #82aaff !important;
}
.hljs-built_in,
.hljs-class {
color: #82aaff;
}
// 括号
.hljs-params {
color: #a6accd;
}
.hljs-attr,
.hljs-variable,
.hljs-template-variable,
.hljs-selector-class,
.hljs-selector-attr,
.hljs-selector-pseudo,
.hljs-number {
color: #de7e61;
}
.hljs-symbol,
.hljs-bullet,
.hljs-link,
.hljs-meta,
.hljs-selector-id {
color: #61aeee;
}
.hljs-strong {
font-weight: bold;
}
.hljs-link {
text-decoration: underline;
}

View File

@@ -0,0 +1,150 @@
@charset "UTF-8";
body,
dl,
dt,
dd,
ul,
ol,
li,
pre,
form,
fieldset,
input,
p,
blockquote,
th,
td {
font-weight: 400;
margin: 0;
padding: 0;
}
h1,
h2,
h3,
h4,
h4,
h5 {
margin: 0;
padding: 0;
color: var(--art-text-gray-800);
}
body {
color: var(--art-text-gray-700);
text-align: left;
font-family:
Inter, 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei',
'微软雅黑', Arial, sans-serif;
}
select {
font-size: 12px;
}
table {
border-collapse: collapse;
}
fieldset,
img {
border: 0none;
}
fieldset {
margin: 0;
padding: 0;
}
fieldset p {
margin: 0;
padding: 0008px;
}
legend {
display: none;
}
address,
caption,
em,
strong,
th,
i {
font-style: normal;
font-weight: 400;
}
table caption {
margin-left: -1px;
}
hr {
border-bottom: 1pxsolid #ffffff;
border-top: 1pxsolid #e4e4e4;
border-width: 1px0;
clear: both;
height: 2px;
margin: 5px0;
overflow: hidden;
}
ol,
ul {
list-style-image: none;
list-style-position: outside;
list-style-type: none;
}
caption,
th {
text-align: left;
}
q:before,
q:after,
blockquote:before,
blockquote:after {
content: ;
}
/*滚动条*/
/*滚动条整体部分,必须要设置*/
::-webkit-scrollbar {
width: 8px !important;
height: 0 !important;
}
/*滚动条的轨道*/
::-webkit-scrollbar-track {
background-color: var(--art-text-gray-100);
}
/*滚动条的滑块按钮*/
::-webkit-scrollbar-thumb {
border-radius: 5px;
background-color: #cccccc !important;
transition: all 0.2s;
-webkit-transition: all 0.2s;
}
::-webkit-scrollbar-thumb:hover {
background-color: #b0abab !important;
}
/*滚动条的上下两端的按钮*/
::-webkit-scrollbar-button {
height: 0px;
width: 0;
}
.dark {
::-webkit-scrollbar-track {
background-color: var(--art-bg-color);
}
::-webkit-scrollbar-thumb {
background-color: rgba(var(--art-gray-300-rgb), 0.8) !important;
}
}

View File

@@ -0,0 +1,63 @@
// 定义基础变量
$bg-animation-color-light: #000;
$bg-animation-color-dark: #fff;
$bg-animation-duration: 0.5s;
html {
--bg-animation-color: $bg-animation-color-light;
&.dark {
--bg-animation-color: $bg-animation-color-dark;
}
// View transition styles
&::view-transition-old(*) {
animation: none;
}
&::view-transition-new(*) {
animation: clip $bg-animation-duration ease-in;
}
&::view-transition-old(root) {
z-index: 1;
}
&::view-transition-new(root) {
z-index: 9999;
}
&.dark {
&::view-transition-old(*) {
animation: clip $bg-animation-duration ease-in reverse;
}
&::view-transition-new(*) {
animation: none;
}
&::view-transition-old(root) {
z-index: 9999;
}
&::view-transition-new(root) {
z-index: 1;
}
}
}
// 定义动画
@keyframes clip {
from {
clip-path: circle(0% at var(--x) var(--y));
}
to {
clip-path: circle(var(--r) at var(--x) var(--y));
}
}
// body 相关样式
body {
background-color: var(--bg-animation-color);
}

View File

@@ -0,0 +1,97 @@
@use 'sass:map';
// === 变量区域 ===
$transition: (
duration: 0.26s,
// 动画持续时间
distance: 20px,
// 滑动动画的移动距离
easing: cubic-bezier(0.4, 0, 0.2, 1),
// 默认缓动函数
fade-easing: ease // 淡入淡出专用的缓动函数
);
// 抽取配置值函数,提高可复用性
@function transition-config($key) {
@return map.get($transition, $key);
}
// 变量简写
$duration: transition-config('duration');
$distance: transition-config('distance');
$easing: transition-config('easing');
$fade-easing: transition-config('fade-easing');
// === 动画类 ===
// 淡入淡出动画
.fade {
&-enter-active,
&-leave-active {
transition: opacity $duration $fade-easing;
will-change: opacity;
}
&-enter-from,
&-leave-to {
opacity: 0;
}
&-enter-to,
&-leave-from {
opacity: 1;
}
}
// 滑动动画通用样式
@mixin slide-transition($direction) {
$distance-x: 0;
$distance-y: 0;
@if $direction == 'left' {
$distance-x: -$distance;
} @else if $direction == 'right' {
$distance-x: $distance;
} @else if $direction == 'top' {
$distance-y: -$distance;
} @else if $direction == 'bottom' {
$distance-y: $distance;
}
&-enter-active,
&-leave-active {
transition:
opacity $duration $easing,
transform $duration $easing;
will-change: opacity, transform;
}
&-enter-from {
opacity: 0;
transform: translate3d($distance-x, $distance-y, 0);
}
&-enter-to {
opacity: 1;
transform: translate3d(0, 0, 0);
}
&-leave-to {
opacity: 0;
transform: translate3d(-$distance-x, -$distance-y, 0);
}
}
// 滑动动画方向类
.slide-left {
@include slide-transition('left');
}
.slide-right {
@include slide-transition('right');
}
.slide-top {
@include slide-transition('top');
}
.slide-bottom {
@include slide-transition('bottom');
}

150
src/assets/styles/tree.scss Normal file
View File

@@ -0,0 +1,150 @@
// 自定义Element树形结构组件样式
.tree .custom-tree-node {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
padding-right: 8px;
}
.tree .tree .el-tree-node__content {
height: 38px;
line-height: 38px;
}
.el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content {
background-color: #409eff;
color: #fff;
}
.el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content i {
color: #fff;
}
.tree .custom-tree-node .icon {
font-size: 13px;
color: #409eff;
}
.tree .custom-tree-node .btn {
font-size: 13px;
display: none;
padding: 6px;
position: relative;
}
.tree .custom-tree-node:hover .icon {
color: #409eff;
}
.tree .el-tree-node__content:hover {
color: #606060;
// background: #409EFF;
background: #f0f7ff;
}
.tree .custom-tree-node:hover .btn {
display: inline;
}
.tree .custom-tree-node .btn:hover ul {
display: inline;
}
.tree .custom-tree-node .btn ul {
width: 120px;
background: #fff;
position: absolute;
top: 26px;
right: 0;
display: none;
z-index: 999;
border: 1px solid #f0f0f0;
// box-shadow: 0 4px 4px 2px #f2f2f2;
}
.tree .custom-tree-node .btn ul li {
padding: 10px 15px;
color: #666666;
box-sizing: border-box;
}
.tree .custom-tree-node .btn ul li:hover {
color: #333;
background: #f5f5f5;
}
.tree .el-tree-node.is-expanded > .el-tree-node__children {
overflow: inherit;
}
.tree .el-tree > .el-tree-node:after {
border-top: none;
}
.tree .el-tree-node {
position: relative;
}
.tree .el-tree-node__expand-icon.is-leaf {
display: none;
}
.tree .el-tree-node__children {
padding-left: 16px;
}
.tree .el-tree-node :last-child:before {
height: 38px;
}
.tree .el-tree-node :last-child:before {
height: 17px;
}
.tree .el-tree > .el-tree-node:before {
border-left: none;
}
.tree .el-tree > .el-tree-node:after {
border-top: none;
}
.tree .el-tree-node:before {
content: '';
position: absolute;
left: -4px;
right: auto;
border-width: 1px;
}
.tree .el-tree-node:after {
content: '';
left: -4px;
position: absolute;
right: auto;
border-width: 1px;
}
.tree .el-tree-node:before {
border-left: 1px dashed #dcdfe6;
bottom: 0px;
height: 100%;
top: -3px;
width: 1px;
left: 14px;
}
.tree .el-tree-node:after {
border-top: 1px dashed #dcdfe6;
height: 20px;
top: 13px;
left: 15px;
width: 12px;
}
.tree-color {
background: #f7fafe;
}

View File

@@ -0,0 +1,251 @@
// Light 主题变量 Dark 主题变量
:root {
// Theme color
--art-primary: 93, 135, 255;
--art-secondary: 73, 190, 255;
--art-error: 250, 137, 107;
--art-info: 83, 155, 255;
--art-success: 19, 222, 185;
--art-warning: 255, 174, 31;
--art-danger: 255, 77, 79;
// Theme background color
--art-bg-primary: 236, 242, 255;
--art-bg-secondary: 232, 247, 255;
--art-bg-success: 230, 255, 250;
--art-bg-error: 253, 237, 232;
--art-bg-info: 235, 243, 254;
--art-bg-warning: 254, 245, 229;
--art-bg-danger: 253, 237, 232;
--art-hoverColor: 246, 249, 252;
--art-grey100: 242, 246, 250;
--art-grey200: 234, 239, 244;
--art-color: #ffffff;
--art-light: #f9f9f9;
--art-dark: #1e2129;
// Background color | Hover color
--art-text-muted: #99a1b7;
--art-gray-100: #f9f9f9;
--art-gray-100-rgb: 249, 249, 249;
--art-gray-200: #f1f1f4;
--art-gray-200-rgb: 241, 241, 244;
--art-gray-300: #dbdfe9;
--art-gray-300-rgb: 219, 223, 233;
--art-gray-400: #c4cada;
--art-gray-400-rgb: 196, 202, 218;
--art-gray-500: #99a1b7;
--art-gray-500-rgb: 153, 161, 183;
--art-gray-600: #78829d;
--art-gray-600-rgb: 120, 130, 157;
--art-gray-700: #4b5675;
--art-gray-700-rgb: 75, 86, 117;
--art-gray-800: #252f4a;
--art-gray-800-rgb: 37, 47, 74;
--art-gray-900: #071437;
--art-gray-900-rgb: 7, 20, 55;
// Text color
--art-text-muted: #99a1b7;
--art-text-gray-100: #f9f9f9;
--art-text-gray-200: #f1f1f4;
--art-text-gray-300: #dbdfe9;
--art-text-gray-400: #c4cada;
--art-text-gray-500: #99a1b7;
--art-text-gray-600: #78829d;
--art-text-gray-700: #4b5675;
--art-text-gray-800: #252f4a;
--art-text-gray-900: #071437;
// Border
--art-border-color: #eaebf1;
--art-border-dashed-color: #dbdfe9;
--art-root-card-border-color: #f1f1f4;
// Shadow
--art-box-shadow-xs: 0 0.1rem 0.75rem 0.25rem rgba(0, 0, 0, 0.05);
--art-box-shadow-sm: 0 0.1rem 1rem 0.25rem rgba(0, 0, 0, 0.05);
--art-box-shadow: 0 0.5rem 1.5rem 0.5rem rgba(0, 0, 0, 0.075);
--art-box-shadow-lg: 0 1rem 2rem 1rem rgba(0, 0, 0, 0.1);
// Root card box、shadow
--art-root-card-box-shadow: 0px 3px 4px 0px rgba(0, 0, 0, 0.03);
--art-root-card-border-color: #f1f1f4;
// Theme background color
--art-bg-color: #fafbfc; // 最底部背景颜色
--art-main-bg-color: #ffffff;
}
// Dark 主题变量
html.dark {
// Theme color
--art-primary: 93, 135, 255;
--art-secondary: 73, 190, 255;
--art-error: 250, 137, 107;
--art-info: 83, 155, 255;
--art-success: 19, 222, 185;
--art-warning: 255, 174, 31;
--art-danger: 255, 77, 79;
// Theme background color
--art-bg-primary: 37, 54, 98;
--art-bg-secondary: 28, 69, 93;
--art-bg-success: 27, 60, 72;
--art-bg-error: 75, 49, 61;
--art-bg-info: 34, 54, 98;
--art-bg-warning: 77, 58, 42;
--art-bg-danger: 100, 49, 61;
--art-hoverColor: 51, 63, 85;
--art-grey100: 51, 63, 85;
--art-grey200: 70, 86, 112;
--art-color: #000000;
--art-light: #1b1c22;
--art-dark: #272a34;
// Background color | Hover color
--art-text-muted: #636674;
--art-gray-100: #1b1c22;
--art-gray-100-rgb: 27, 28, 34;
--art-gray-200: #26272f;
--art-gray-200-rgb: 38, 39, 47;
--art-gray-300: #363843;
--art-gray-300-rgb: 54, 56, 67;
--art-gray-400: #464852;
--art-gray-400-rgb: 70, 72, 82;
--art-gray-500: #636674;
--art-gray-500-rgb: 99, 102, 116;
--art-gray-600: #808290;
--art-gray-600-rgb: 128, 130, 144;
--art-gray-700: #9a9cae;
--art-gray-700-rgb: 154, 156, 174;
--art-gray-800: #b5b7c8;
--art-gray-800-rgb: 181, 183, 200;
--art-gray-900: #f5f5f5;
--art-gray-900-rgb: 245, 245, 245;
// Text color
--art-text-muted: #636674;
--art-text-gray-100: #1b1c22;
--art-text-gray-200: #26272f;
--art-text-gray-300: #363843;
--art-text-gray-400: #464852;
--art-text-gray-500: #636674;
--art-text-gray-600: #808290;
--art-text-gray-700: #9a9cae;
--art-text-gray-800: #b5b7c8;
--art-text-gray-900: #f5f5f5;
// Border
--art-border-color: #26272f;
--art-border-dashed-color: #363843;
--art-root-card-border-color: #1e2027;
// Shadow
--art-box-shadow-xs: 0 0.1rem 0.75rem 0.25rem rgba(0, 0, 0, 0.05);
--art-box-shadow-sm: 0 0.1rem 1rem 0.25rem rgba(0, 0, 0, 0.05);
--art-box-shadow: 0 0.5rem 1.5rem 0.5rem rgba(0, 0, 0, 0.075);
--art-box-shadow-lg: 0 1rem 2rem 1rem rgba(0, 0, 0, 0.1);
// Root card box、shadow
--art-root-card-box-shadow: none;
--art-root-card-border-color: #1e2027;
// Theme background color
--art-bg-color: #070707;
--art-main-bg-color: #161618;
}
// CSS 全局变量
:root {
--art-card-border: rgba(var(--art-gray-300-rgb), 0.6); // 卡片边框颜色
--art-card-shadow: 0px 0px 4px 0px rgba(0, 0, 0, 0.04); // 卡片阴影
}
// 媒体查询-设备尺寸
// notebook
$device-notebook: 1600px;
// ipad pro
$device-ipad-pro: 1180px;
// ipad
$device-ipad: 800px;
// ipad-竖屏
$device-ipad-vertical: 900px;
// mobile
$device-phone: 500px;
.bg-primary {
background-color: rgb(var(--art-bg-primary)) !important;
color: rgb(var(--art-primary)) !important;
}
.bg-secondary {
background-color: rgb(var(--art-bg-secondary)) !important;
color: rgb(var(--art-secondary)) !important;
border: 1px solid var(--art-secondary);
}
.bg-warning {
background-color: rgb(var(--art-bg-warning)) !important;
color: rgb(var(--art-warning)) !important;
}
.bg-error {
background-color: rgb(var(--art-bg-error)) !important;
color: rgb(var(--art-error)) !important;
}
.bg-success {
background-color: rgb(var(--art-bg-success)) !important;
color: rgb(var(--art-success)) !important;
}
.bg-danger {
background-color: rgb(var(--art-bg-danger)) !important;
color: rgb(var(--art-danger)) !important;
}
.bg-grey100 {
background-color: rgb(var(--art-grey100)) !important;
}
.bg-grey200 {
background-color: rgb(var(--art-grey200)) !important;
}
.bg-hoverColor {
background-color: rgb(var(--art-hoverColor)) !important;
}
.text-primary {
color: rgb(var(--art-primary)) !important;
}
.text-secondary {
color: rgb(var(--art-secondary)) !important;
}
.text-error {
color: rgb(var(--art-error)) !important;
}
.text-danger {
color: rgb(var(--art-danger)) !important;
}
.text-info {
color: rgb(var(--art-info)) !important;
}
.text-success {
color: rgb(var(--art-success)) !important;
}
.text-warning {
color: rgb(var(--art-warning)) !important;
}

32
src/assets/svg/loading.ts Normal file
View File

@@ -0,0 +1,32 @@
// 自定义四点旋转SVG
export const fourDotsSpinnerSvg = `
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 40 40">
<style>
.spinner {
transform-origin: center;
animation: rotate 1.6s linear infinite;
}
.dot {
fill: var(--main-color);
animation: fade 1.6s infinite;
}
.dot:nth-child(1) { animation-delay: 0s; }
.dot:nth-child(2) { animation-delay: 0.5s; }
.dot:nth-child(3) { animation-delay: 1s; }
.dot:nth-child(4) { animation-delay: 1.5s; }
@keyframes rotate {
100% { transform: rotate(360deg); }
}
@keyframes fade {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
</style>
<g class="spinner">
<circle class="dot" cx="20" cy="8" r="4"/>
<circle class="dot" cx="32" cy="20" r="4"/>
<circle class="dot" cx="20" cy="32" r="4"/>
<circle class="dot" cx="8" cy="20" r="4"/>
</g>
</svg>
`