refactor: 移除ant-design-vue和tailwindcss依赖并优化样式
style: 统一使用css替换scss并调整组件样式 style: 优化组件布局和属性顺序 chore: 更新.gitignore和.eslintrc配置
This commit is contained in:
@@ -19,11 +19,6 @@
|
||||
--el-color-info-light-9: #a6a9ad;
|
||||
--el-color-info-light-3: #c8c9cc;
|
||||
--el-color-info-dark-2: #73767a;
|
||||
|
||||
--border-radius-base: 8px;
|
||||
--border-radius-large: 12px;
|
||||
--border-radius-small: 4px;
|
||||
--border-radius-circle: 50%;
|
||||
}
|
||||
|
||||
* {
|
||||
@@ -37,676 +32,3 @@ body {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.el-card {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.el-card:hover {
|
||||
box-shadow: 0 4px 16px 0 rgba(0, 0, 0, 0.12);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.el-button {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.el-button--primary {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
border: none;
|
||||
}
|
||||
|
||||
.el-button--primary:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
|
||||
}
|
||||
|
||||
.el-input__wrapper {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.el-input__wrapper:hover {
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.el-select .el-input__wrapper {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-table {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.el-table th {
|
||||
background: linear-gradient(135deg, #f5f7fa 0%, #e4e7ed 100%);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.el-table tr {
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.el-table tr:hover {
|
||||
background-color: #f0f9ff !important;
|
||||
}
|
||||
|
||||
.el-table .el-table__cell {
|
||||
border-radius: var(--border-radius-small);
|
||||
}
|
||||
|
||||
.el-pagination {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-pagination .el-pager li {
|
||||
border-radius: var(--border-radius-small) !important;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.el-pagination .el-pager li:hover {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
.el-dialog {
|
||||
border-radius: var(--border-radius-large) !important;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.el-dialog__header {
|
||||
border-radius: var(--border-radius-large) var(--border-radius-large) 0 0 !important;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.el-dialog__body {
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.el-form-item__label {
|
||||
font-weight: 500;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
.el-form-item {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.el-menu {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.el-menu-item {
|
||||
border-radius: var(--border-radius-small) !important;
|
||||
margin: 4px 8px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.el-menu-item:hover {
|
||||
background: linear-gradient(135deg, #667eea20 0%, #764ba220 100%);
|
||||
transform: translateX(4px);
|
||||
}
|
||||
|
||||
.el-menu-item.is-active {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.el-statistic {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.el-statistic:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.el-timeline-item__tail {
|
||||
border-radius: var(--border-radius-small);
|
||||
}
|
||||
|
||||
.el-timeline-item__node {
|
||||
border-radius: var(--border-radius-circle) !important;
|
||||
}
|
||||
|
||||
.el-tag {
|
||||
border-radius: var(--border-radius-small) !important;
|
||||
padding: 4px 12px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.el-tag--success {
|
||||
background: linear-gradient(135deg, #67c23a 0%, #5daf34 100%);
|
||||
border: none;
|
||||
}
|
||||
|
||||
.el-tag--warning {
|
||||
background: linear-gradient(135deg, #e6a23c 0%, #d93026 100%);
|
||||
border: none;
|
||||
}
|
||||
|
||||
.el-tag--info {
|
||||
background: linear-gradient(135deg, #909399 0%, #73767a 100%);
|
||||
border: none;
|
||||
}
|
||||
|
||||
.el-descriptions {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-descriptions__label {
|
||||
font-weight: 600;
|
||||
background: #f5f7fa;
|
||||
}
|
||||
|
||||
.el-message-box {
|
||||
border-radius: var(--border-radius-large) !important;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.el-notification {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.el-drawer {
|
||||
border-radius: var(--border-radius-large) var(--border-radius-large) 0 0 !important;
|
||||
}
|
||||
|
||||
.el-switch {
|
||||
border-radius: var(--border-radius-circle) !important;
|
||||
}
|
||||
|
||||
.el-checkbox {
|
||||
border-radius: var(--border-radius-small) !important;
|
||||
}
|
||||
|
||||
.el-radio {
|
||||
border-radius: var(--border-radius-small) !important;
|
||||
}
|
||||
|
||||
.el-upload {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-upload-dragger {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
border: 2px dashed #dcdfe6;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.el-upload-dragger:hover {
|
||||
border-color: #667eea;
|
||||
background: #f0f9ff;
|
||||
}
|
||||
|
||||
.el-progress-bar__inner {
|
||||
border-radius: var(--border-radius-small) !important;
|
||||
}
|
||||
|
||||
.el-progress-bar {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-rate__icon {
|
||||
border-radius: var(--border-radius-small) !important;
|
||||
}
|
||||
|
||||
.el-slider__runway {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-slider__button {
|
||||
border-radius: var(--border-radius-circle) !important;
|
||||
}
|
||||
|
||||
.el-avatar {
|
||||
border-radius: var(--border-radius-circle) !important;
|
||||
}
|
||||
|
||||
.el-badge__content {
|
||||
border-radius: var(--border-radius-circle) !important;
|
||||
}
|
||||
|
||||
.el-breadcrumb {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
padding: 8px 16px;
|
||||
}
|
||||
|
||||
.el-breadcrumb__item {
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.el-breadcrumb__item:hover {
|
||||
color: #667eea;
|
||||
}
|
||||
|
||||
.el-divider {
|
||||
border-radius: var(--border-radius-small) !important;
|
||||
}
|
||||
|
||||
.el-empty {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-result {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-alert {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.el-alert--success {
|
||||
background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%);
|
||||
}
|
||||
|
||||
.el-alert--warning {
|
||||
background: linear-gradient(135deg, #fdf6ec 0%, #fef0f0 100%);
|
||||
}
|
||||
|
||||
.el-alert--error {
|
||||
background: linear-gradient(135deg, #fef0f0 0%, #fde2e2 100%);
|
||||
}
|
||||
|
||||
.el-alert--info {
|
||||
background: linear-gradient(135deg, #f4f4f5 0%, #e9e9eb 100%);
|
||||
}
|
||||
|
||||
.el-tabs__item {
|
||||
border-radius: var(--border-radius-base) var(--border-radius-base) 0 0 !important;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.el-tabs__item:hover {
|
||||
color: #667eea;
|
||||
}
|
||||
|
||||
.el-tabs__item.is-active {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.el-collapse {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-collapse-item__header {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.el-collapse-item__header:hover {
|
||||
background: #f5f7fa;
|
||||
}
|
||||
|
||||
.el-popover {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.el-tooltip__popper {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-dropdown-menu {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.el-dropdown-menu__item {
|
||||
border-radius: var(--border-radius-small) !important;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.el-dropdown-menu__item:hover {
|
||||
background: linear-gradient(135deg, #667eea20 0%, #764ba220 100%);
|
||||
transform: translateX(4px);
|
||||
}
|
||||
|
||||
.el-tree-node__content {
|
||||
border-radius: var(--border-radius-small) !important;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.el-tree-node__content:hover {
|
||||
background: #f0f9ff;
|
||||
}
|
||||
|
||||
.el-transfer-panel {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-cascader-panel {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-color-picker__panel {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-date-picker {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-picker-panel {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.el-calendar {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-image {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-skeleton {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-backtop {
|
||||
border-radius: var(--border-radius-circle) !important;
|
||||
}
|
||||
|
||||
.el-affix {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-space {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-tour {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-segmented {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-timeline {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-timeline-item {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-scrollbar {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-main {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-header {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-footer {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-aside {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-container {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-row {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-col {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-form {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-input-number {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-select-dropdown {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.el-option {
|
||||
border-radius: var(--border-radius-small) !important;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.el-option:hover {
|
||||
background: #f0f9ff;
|
||||
}
|
||||
|
||||
.el-option-group {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-option-group__title {
|
||||
border-radius: var(--border-radius-base) var(--border-radius-base) 0 0 !important;
|
||||
}
|
||||
|
||||
.el-checkbox-group {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-checkbox-button {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-radio-group {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-radio-button {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-check-tag {
|
||||
border-radius: var(--border-radius-small) !important;
|
||||
}
|
||||
|
||||
.el-select-v2 {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-select-dropdown-v2 {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-select-dropdown-v2__item {
|
||||
border-radius: var(--border-radius-small) !important;
|
||||
}
|
||||
|
||||
.el-select-dropdown-v2__item:hover {
|
||||
background: #f0f9ff;
|
||||
}
|
||||
|
||||
.el-table-v2 {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-table-column {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-table-v2__row {
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.el-table-v2__row:hover {
|
||||
background: #f0f9ff !important;
|
||||
}
|
||||
|
||||
.el-page-header {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-overlay {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-notification__group {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-notification__icon {
|
||||
border-radius: var(--border-radius-circle) !important;
|
||||
}
|
||||
|
||||
.el-notification__content {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-notification__closeBtn {
|
||||
border-radius: var(--border-radius-circle) !important;
|
||||
}
|
||||
|
||||
.el-message {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.el-message__icon {
|
||||
border-radius: var(--border-radius-circle) !important;
|
||||
}
|
||||
|
||||
.el-message__content {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-message-box__btns {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-menu-item-group {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-menu-item-group__title {
|
||||
border-radius: var(--border-radius-base) var(--border-radius-base) 0 0 !important;
|
||||
}
|
||||
|
||||
.el-mention {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-loading-spinner {
|
||||
border-radius: var(--border-radius-circle) !important;
|
||||
}
|
||||
|
||||
.el-link {
|
||||
border-radius: var(--border-radius-small) !important;
|
||||
}
|
||||
|
||||
.el-input-tag {
|
||||
border-radius: var(--border-radius-small) !important;
|
||||
}
|
||||
|
||||
.el-infinite-scroll {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-image-viewer {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-icon {
|
||||
border-radius: var(--border-radius-small) !important;
|
||||
}
|
||||
|
||||
.el-result__icon {
|
||||
border-radius: var(--border-radius-circle) !important;
|
||||
}
|
||||
|
||||
.el-result__title {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-result__subtitle {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-result__extra {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-result__content {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-descriptions-item {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-descriptions-item__label {
|
||||
border-radius: var(--border-radius-base) var(--border-radius-base) 0 0 !important;
|
||||
}
|
||||
|
||||
.el-descriptions-item__content {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-descriptions-item__cell {
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
}
|
||||
|
||||
.el-date-picker__header {
|
||||
border-radius: var(--border-radius-base) var(--border-radius-base) 0 0 !important;
|
||||
}
|
||||
|
||||
.el-date-picker__header-label {
|
||||
border-radius: var(--border-radius-small) !important;
|
||||
}
|
||||
|
||||
.el-date-picker__time-header {
|
||||
border-radius: var(--border-radius-base) var(--border-radius-base) 0 0 !important;
|
||||
}
|
||||
|
||||
.el-date-picker__time-picker-option {
|
||||
border-radius: var(--border-radius-small) !important;
|
||||
}
|
||||
|
||||
.el-date-picker__time-picker-option:hover {
|
||||
background: #f0f9ff;
|
||||
}
|
||||
|
||||
.el-date-picker__time-picker-option.is-selected {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.el-date-picker__time-picker-option.is-disabled {
|
||||
background: #f5f7fa;
|
||||
color: #c0c4cc;
|
||||
}
|
||||
|
||||
.el-date-picker__time-picker-option.is-disabled:hover {
|
||||
background: #f5f7fa;
|
||||
}
|
||||
|
||||
.el-date-picker__time-picker-option.is-disabled.is-selected {
|
||||
background: #f5f7fa;
|
||||
color: #c0c4cc;
|
||||
}
|
||||
|
||||
.el-date-picker__time-picker-option.is-disabled.is-selected:hover {
|
||||
background: #f5f7fa;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
<template>
|
||||
<el-container class="default-layout">
|
||||
<el-aside :width="collapsed ? '64px' : '200px'" class="aside">
|
||||
<el-aside
|
||||
:width="collapsed ? '64px' : '200px'"
|
||||
class="aside"
|
||||
>
|
||||
<div class="logo">
|
||||
<span v-if="!collapsed">Novalon</span>
|
||||
<span v-else>N</span>
|
||||
@@ -9,8 +12,8 @@
|
||||
:default-active="activeMenu"
|
||||
class="menu"
|
||||
:collapse="collapsed"
|
||||
background-color="#304156"
|
||||
text-color="#bfcbd9"
|
||||
background-color="#f5f7fa"
|
||||
text-color="#606266"
|
||||
active-text-color="#409eff"
|
||||
router
|
||||
>
|
||||
@@ -23,55 +26,85 @@
|
||||
<el-icon><Setting /></el-icon>
|
||||
<span>系统管理</span>
|
||||
</template>
|
||||
<el-menu-item index="/users">用户管理</el-menu-item>
|
||||
<el-menu-item index="/roles">角色管理</el-menu-item>
|
||||
<el-menu-item index="/menus">菜单管理</el-menu-item>
|
||||
<el-menu-item index="/users">
|
||||
用户管理
|
||||
</el-menu-item>
|
||||
<el-menu-item index="/roles">
|
||||
角色管理
|
||||
</el-menu-item>
|
||||
<el-menu-item index="/menus">
|
||||
菜单管理
|
||||
</el-menu-item>
|
||||
</el-sub-menu>
|
||||
<el-sub-menu index="config">
|
||||
<template #title>
|
||||
<el-icon><Tools /></el-icon>
|
||||
<span>系统配置</span>
|
||||
</template>
|
||||
<el-menu-item index="/dict">字典管理</el-menu-item>
|
||||
<el-menu-item index="/sysconfig">参数配置</el-menu-item>
|
||||
<el-menu-item index="/dict">
|
||||
字典管理
|
||||
</el-menu-item>
|
||||
<el-menu-item index="/sysconfig">
|
||||
参数配置
|
||||
</el-menu-item>
|
||||
</el-sub-menu>
|
||||
<el-sub-menu index="audit">
|
||||
<template #title>
|
||||
<el-icon><Document /></el-icon>
|
||||
<span>审计中心</span>
|
||||
</template>
|
||||
<el-menu-item index="/loginlog">登录日志</el-menu-item>
|
||||
<el-menu-item index="/oplog">操作日志</el-menu-item>
|
||||
<el-menu-item index="/loginlog">
|
||||
登录日志
|
||||
</el-menu-item>
|
||||
<el-menu-item index="/oplog">
|
||||
操作日志
|
||||
</el-menu-item>
|
||||
</el-sub-menu>
|
||||
<el-sub-menu index="notify">
|
||||
<template #title>
|
||||
<el-icon><Bell /></el-icon>
|
||||
<span>通知中心</span>
|
||||
</template>
|
||||
<el-menu-item index="/notice">通知公告</el-menu-item>
|
||||
<el-menu-item index="/notice">
|
||||
通知公告
|
||||
</el-menu-item>
|
||||
</el-sub-menu>
|
||||
<el-sub-menu index="file">
|
||||
<template #title>
|
||||
<el-icon><Folder /></el-icon>
|
||||
<span>文件管理</span>
|
||||
</template>
|
||||
<el-menu-item index="/files">文件列表</el-menu-item>
|
||||
<el-menu-item index="/files">
|
||||
文件列表
|
||||
</el-menu-item>
|
||||
</el-sub-menu>
|
||||
</el-menu>
|
||||
</el-aside>
|
||||
<el-container>
|
||||
<el-header class="header">
|
||||
<el-icon class="trigger" @click="collapsed = !collapsed">
|
||||
<el-icon
|
||||
class="trigger"
|
||||
@click="collapsed = !collapsed"
|
||||
>
|
||||
<Fold v-if="!collapsed" />
|
||||
<Expand v-else />
|
||||
</el-icon>
|
||||
<div class="header-right">
|
||||
<el-dropdown @command="handleCommand">
|
||||
<el-avatar :size="32">{{ username }}</el-avatar>
|
||||
<el-avatar :size="32">
|
||||
{{ username }}
|
||||
</el-avatar>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item command="profile">个人中心</el-dropdown-item>
|
||||
<el-dropdown-item command="logout" divided>退出登录</el-dropdown-item>
|
||||
<el-dropdown-item command="profile">
|
||||
个人中心
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
command="logout"
|
||||
divided
|
||||
>
|
||||
退出登录
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
@@ -114,13 +147,13 @@ onMounted(() => {
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
<style scoped lang="css">
|
||||
.default-layout {
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.aside {
|
||||
background-color: #304156;
|
||||
background-color: #f5f7fa;
|
||||
transition: width 0.3s;
|
||||
overflow: hidden;
|
||||
}
|
||||
@@ -130,7 +163,7 @@ onMounted(() => {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #fff;
|
||||
color: #303133;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@@ -16,17 +16,51 @@
|
||||
<el-icon><Search /></el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
<el-button type="primary" @click="handleSearch">搜索</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="handleSearch"
|
||||
>
|
||||
搜索
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<el-table :data="dataSource" v-loading="loading" style="width: 100%" @sort-change="handleSortChange">
|
||||
<el-table-column prop="id" label="ID" sortable="custom" />
|
||||
<el-table-column prop="username" label="用户名" sortable="custom" />
|
||||
<el-table-column prop="ip" label="IP地址" sortable="custom" />
|
||||
<el-table-column prop="location" label="登录地点" sortable="custom" />
|
||||
<el-table-column prop="browser" label="浏览器" sortable="custom" />
|
||||
<el-table-column prop="os" label="操作系统" sortable="custom" />
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="dataSource"
|
||||
style="width: 100%"
|
||||
@sort-change="handleSortChange"
|
||||
>
|
||||
<el-table-column
|
||||
prop="id"
|
||||
label="ID"
|
||||
sortable="custom"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="username"
|
||||
label="用户名"
|
||||
sortable="custom"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="ip"
|
||||
label="IP地址"
|
||||
sortable="custom"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="location"
|
||||
label="登录地点"
|
||||
sortable="custom"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="browser"
|
||||
label="浏览器"
|
||||
sortable="custom"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="os"
|
||||
label="操作系统"
|
||||
sortable="custom"
|
||||
/>
|
||||
<el-table-column label="状态">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="row.status === '0' ? 'success' : 'danger'">
|
||||
@@ -34,17 +68,21 @@
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="loginTime" label="登录时间" sortable="custom" />
|
||||
<el-table-column
|
||||
prop="loginTime"
|
||||
label="登录时间"
|
||||
sortable="custom"
|
||||
/>
|
||||
</el-table>
|
||||
<el-pagination
|
||||
v-model:current-page="pagination.current"
|
||||
v-model:page-size="pagination.pageSize"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
:total="pagination.total"
|
||||
@current-change="handleTableChange"
|
||||
@size-change="handleSizeChange"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
style="margin-top: 16px; justify-content: flex-end"
|
||||
@current-change="handleTableChange"
|
||||
@size-change="handleSizeChange"
|
||||
/>
|
||||
</el-card>
|
||||
</div>
|
||||
@@ -111,7 +149,7 @@ const handleSortChange = ({ prop, order }: any) => {
|
||||
onMounted(() => fetchData())
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
<style scoped lang="css">
|
||||
.login-log {
|
||||
.card-header {
|
||||
display: flex;
|
||||
|
||||
@@ -16,16 +16,46 @@
|
||||
<el-icon><Search /></el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
<el-button type="primary" @click="handleSearch">搜索</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="handleSearch"
|
||||
>
|
||||
搜索
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<el-table :data="dataSource" v-loading="loading" style="width: 100%" @sort-change="handleSortChange">
|
||||
<el-table-column prop="id" label="ID" sortable="custom" />
|
||||
<el-table-column prop="username" label="操作人" sortable="custom" />
|
||||
<el-table-column prop="operation" label="操作模块" sortable="custom" />
|
||||
<el-table-column prop="method" label="请求方法" sortable="custom" />
|
||||
<el-table-column prop="params" label="请求参数" :show-overflow-tooltip="true" />
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="dataSource"
|
||||
style="width: 100%"
|
||||
@sort-change="handleSortChange"
|
||||
>
|
||||
<el-table-column
|
||||
prop="id"
|
||||
label="ID"
|
||||
sortable="custom"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="username"
|
||||
label="操作人"
|
||||
sortable="custom"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="operation"
|
||||
label="操作模块"
|
||||
sortable="custom"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="method"
|
||||
label="请求方法"
|
||||
sortable="custom"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="params"
|
||||
label="请求参数"
|
||||
:show-overflow-tooltip="true"
|
||||
/>
|
||||
<el-table-column label="状态">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="row.status === '0' ? 'success' : 'danger'">
|
||||
@@ -33,18 +63,26 @@
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="duration" label="耗时(ms)" sortable="custom" />
|
||||
<el-table-column prop="createdAt" label="操作时间" sortable="custom" />
|
||||
<el-table-column
|
||||
prop="duration"
|
||||
label="耗时(ms)"
|
||||
sortable="custom"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="createdAt"
|
||||
label="操作时间"
|
||||
sortable="custom"
|
||||
/>
|
||||
</el-table>
|
||||
<el-pagination
|
||||
v-model:current-page="pagination.current"
|
||||
v-model:page-size="pagination.pageSize"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
:total="pagination.total"
|
||||
@current-change="handleTableChange"
|
||||
@size-change="handleSizeChange"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
style="margin-top: 16px; justify-content: flex-end"
|
||||
@current-change="handleTableChange"
|
||||
@size-change="handleSizeChange"
|
||||
/>
|
||||
</el-card>
|
||||
</div>
|
||||
@@ -111,7 +149,7 @@ const handleSortChange = ({ prop, order }: any) => {
|
||||
onMounted(() => fetchData())
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
<style scoped lang="css">
|
||||
.operation-log {
|
||||
.card-header {
|
||||
display: flex;
|
||||
|
||||
@@ -4,14 +4,35 @@
|
||||
<template #header>
|
||||
<div class="card-title">
|
||||
<span>参数配置</span>
|
||||
<el-button type="primary" @click="handleAdd">新增配置</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="handleAdd"
|
||||
>
|
||||
新增配置
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
<el-table :data="dataSource" v-loading="loading" style="width: 100%">
|
||||
<el-table-column prop="id" label="ID" />
|
||||
<el-table-column prop="configName" label="参数名称" />
|
||||
<el-table-column prop="configKey" label="参数键名" />
|
||||
<el-table-column prop="configValue" label="参数值" />
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="dataSource"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column
|
||||
prop="id"
|
||||
label="ID"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="configName"
|
||||
label="参数名称"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="configKey"
|
||||
label="参数键名"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="configValue"
|
||||
label="参数值"
|
||||
/>
|
||||
<el-table-column label="类型">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="row.configType === 'Y' ? '' : 'info'">
|
||||
@@ -19,17 +40,41 @@
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="150">
|
||||
<el-table-column
|
||||
label="操作"
|
||||
width="150"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" link size="small" @click="handleEdit(row)">编辑</el-button>
|
||||
<el-button type="danger" link size="small" @click="handleDelete(row)">删除</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
size="small"
|
||||
@click="handleEdit(row)"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
type="danger"
|
||||
link
|
||||
size="small"
|
||||
@click="handleDelete(row)"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
|
||||
<el-dialog v-model="modalVisible" :title="modalTitle" width="500px">
|
||||
<el-form :model="formState" label-width="80px">
|
||||
<el-dialog
|
||||
v-model="modalVisible"
|
||||
:title="modalTitle"
|
||||
width="500px"
|
||||
>
|
||||
<el-form
|
||||
:model="formState"
|
||||
label-width="80px"
|
||||
>
|
||||
<el-form-item label="参数名称">
|
||||
<el-input v-model="formState.configName" />
|
||||
</el-form-item>
|
||||
@@ -41,8 +86,15 @@
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="modalVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleModalOk">确定</el-button>
|
||||
<el-button @click="modalVisible = false">
|
||||
取消
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="handleModalOk"
|
||||
>
|
||||
确定
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
@@ -91,7 +143,9 @@ const handleDelete = async (row: any) => {
|
||||
await request.delete(`/config/${row.id}`)
|
||||
ElMessage.success('删除成功')
|
||||
fetchData()
|
||||
} catch {}
|
||||
} catch (error) {
|
||||
console.error('删除配置失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const handleModalOk = async () => {
|
||||
@@ -112,7 +166,7 @@ const handleModalOk = async () => {
|
||||
onMounted(() => fetchData())
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
<style scoped lang="css">
|
||||
.config-management .card-title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
@@ -4,13 +4,31 @@
|
||||
<template #header>
|
||||
<div class="card-title">
|
||||
<span>字典管理</span>
|
||||
<el-button type="primary" @click="handleAdd">新增字典</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="handleAdd"
|
||||
>
|
||||
新增字典
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
<el-table :data="dataSource" v-loading="loading" style="width: 100%">
|
||||
<el-table-column prop="id" label="ID" />
|
||||
<el-table-column prop="dictName" label="字典名称" />
|
||||
<el-table-column prop="dictType" label="字典类型" />
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="dataSource"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column
|
||||
prop="id"
|
||||
label="ID"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="dictName"
|
||||
label="字典名称"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="dictType"
|
||||
label="字典类型"
|
||||
/>
|
||||
<el-table-column label="状态">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="row.status === '0' ? 'success' : 'danger'">
|
||||
@@ -18,18 +36,45 @@
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="remark" label="备注" />
|
||||
<el-table-column label="操作" width="200">
|
||||
<el-table-column
|
||||
prop="remark"
|
||||
label="备注"
|
||||
/>
|
||||
<el-table-column
|
||||
label="操作"
|
||||
width="200"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" link size="small" @click="handleEdit(row)">编辑</el-button>
|
||||
<el-button type="danger" link size="small" @click="handleDelete(row)">删除</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
size="small"
|
||||
@click="handleEdit(row)"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
type="danger"
|
||||
link
|
||||
size="small"
|
||||
@click="handleDelete(row)"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
|
||||
<el-dialog v-model="modalVisible" :title="modalTitle" width="500px">
|
||||
<el-form :model="formState" label-width="80px">
|
||||
<el-dialog
|
||||
v-model="modalVisible"
|
||||
:title="modalTitle"
|
||||
width="500px"
|
||||
>
|
||||
<el-form
|
||||
:model="formState"
|
||||
label-width="80px"
|
||||
>
|
||||
<el-form-item label="字典名称">
|
||||
<el-input v-model="formState.dictName" />
|
||||
</el-form-item>
|
||||
@@ -38,17 +83,33 @@
|
||||
</el-form-item>
|
||||
<el-form-item label="状态">
|
||||
<el-select v-model="formState.status">
|
||||
<el-option value="0" label="正常" />
|
||||
<el-option value="1" label="停用" />
|
||||
<el-option
|
||||
value="0"
|
||||
label="正常"
|
||||
/>
|
||||
<el-option
|
||||
value="1"
|
||||
label="停用"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="formState.remark" type="textarea" />
|
||||
<el-input
|
||||
v-model="formState.remark"
|
||||
type="textarea"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="modalVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleModalOk">确定</el-button>
|
||||
<el-button @click="modalVisible = false">
|
||||
取消
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="handleModalOk"
|
||||
>
|
||||
确定
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
@@ -94,10 +155,12 @@ const handleDelete = async (row: any) => {
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
})
|
||||
await request.delete(`/dict/types/${row.id}`)
|
||||
await request.delete(`/dict/${row.id}`)
|
||||
ElMessage.success('删除成功')
|
||||
fetchData()
|
||||
} catch {}
|
||||
} catch (error) {
|
||||
console.error('删除字典失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const handleModalOk = async () => {
|
||||
@@ -118,7 +181,7 @@ const handleModalOk = async () => {
|
||||
onMounted(() => fetchData())
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
<style scoped lang="css">
|
||||
.dict-management .card-title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
@@ -4,17 +4,33 @@
|
||||
<template #header>
|
||||
<div class="card-title">
|
||||
<span>文件管理</span>
|
||||
<el-upload :before-upload="handleUpload" :show-file-list="false">
|
||||
<el-upload
|
||||
:before-upload="handleUpload"
|
||||
:show-file-list="false"
|
||||
>
|
||||
<el-button type="primary">
|
||||
<el-icon><Upload /></el-icon> 上传文件
|
||||
</el-button>
|
||||
</el-upload>
|
||||
</div>
|
||||
</template>
|
||||
<el-table :data="dataSource" v-loading="loading" style="width: 100%">
|
||||
<el-table-column prop="id" label="ID" />
|
||||
<el-table-column prop="fileName" label="文件名" />
|
||||
<el-table-column prop="fileSize" label="文件大小" />
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="dataSource"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column
|
||||
prop="id"
|
||||
label="ID"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="fileName"
|
||||
label="文件名"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="fileSize"
|
||||
label="文件大小"
|
||||
/>
|
||||
<el-table-column label="文件类型">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="getFileTypeTag(row.fileType)">
|
||||
@@ -22,12 +38,35 @@
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="storageType" label="存储方式" />
|
||||
<el-table-column prop="createdAt" label="上传时间" />
|
||||
<el-table-column label="操作" width="150">
|
||||
<el-table-column
|
||||
prop="storageType"
|
||||
label="存储方式"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="createdAt"
|
||||
label="上传时间"
|
||||
/>
|
||||
<el-table-column
|
||||
label="操作"
|
||||
width="150"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" link size="small" @click="handleDownload(row)">下载</el-button>
|
||||
<el-button type="danger" link size="small" @click="handleDelete(row)">删除</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
size="small"
|
||||
@click="handleDownload(row)"
|
||||
>
|
||||
下载
|
||||
</el-button>
|
||||
<el-button
|
||||
type="danger"
|
||||
link
|
||||
size="small"
|
||||
@click="handleDelete(row)"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -83,7 +122,9 @@ const handleDelete = async (row: any) => {
|
||||
await request.delete(`/files/${row.id}`)
|
||||
ElMessage.success('删除成功')
|
||||
fetchData()
|
||||
} catch {}
|
||||
} catch (error) {
|
||||
console.error('删除文件失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const getFileTypeName = (fileType: string) => {
|
||||
@@ -111,7 +152,7 @@ const getFileTypeTag = (fileType: string): '' | 'success' | 'warning' | 'danger'
|
||||
onMounted(() => fetchData())
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
<style scoped lang="css">
|
||||
.file-management .card-title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
@@ -4,60 +4,131 @@
|
||||
<template #header>
|
||||
<div class="card-title">
|
||||
<span>通知公告</span>
|
||||
<el-button type="primary" @click="handleAdd">新增公告</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="handleAdd"
|
||||
>
|
||||
新增公告
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
<el-table :data="dataSource" v-loading="loading" style="width: 100%">
|
||||
<el-table-column prop="id" label="ID" />
|
||||
<el-table-column prop="noticeTitle" label="公告标题" />
|
||||
<el-table-column label="公告类型" width="100">
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="dataSource"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column
|
||||
prop="id"
|
||||
label="ID"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="noticeTitle"
|
||||
label="公告标题"
|
||||
/>
|
||||
<el-table-column
|
||||
label="公告类型"
|
||||
width="100"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="row.noticeType === '1' ? '' : 'success'">
|
||||
{{ row.noticeType === '1' ? '通知' : '公告' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" width="80">
|
||||
<el-table-column
|
||||
label="状态"
|
||||
width="80"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="row.status === '0' ? 'success' : 'danger'">
|
||||
{{ row.status === '0' ? '正常' : '停用' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createdAt" label="发布时间" />
|
||||
<el-table-column label="操作" width="150">
|
||||
<el-table-column
|
||||
prop="createdAt"
|
||||
label="发布时间"
|
||||
/>
|
||||
<el-table-column
|
||||
label="操作"
|
||||
width="150"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" link size="small" @click="handleEdit(row)">编辑</el-button>
|
||||
<el-button type="danger" link size="small" @click="handleDelete(row)">删除</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
size="small"
|
||||
@click="handleEdit(row)"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
type="danger"
|
||||
link
|
||||
size="small"
|
||||
@click="handleDelete(row)"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
|
||||
<el-dialog v-model="modalVisible" :title="modalTitle" width="500px">
|
||||
<el-form :model="formState" label-width="80px">
|
||||
<el-dialog
|
||||
v-model="modalVisible"
|
||||
:title="modalTitle"
|
||||
width="500px"
|
||||
>
|
||||
<el-form
|
||||
:model="formState"
|
||||
label-width="80px"
|
||||
>
|
||||
<el-form-item label="公告标题">
|
||||
<el-input v-model="formState.noticeTitle" />
|
||||
</el-form-item>
|
||||
<el-form-item label="公告类型">
|
||||
<el-select v-model="formState.noticeType">
|
||||
<el-option value="1" label="通知" />
|
||||
<el-option value="2" label="公告" />
|
||||
<el-option
|
||||
value="1"
|
||||
label="通知"
|
||||
/>
|
||||
<el-option
|
||||
value="2"
|
||||
label="公告"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="公告内容">
|
||||
<el-input v-model="formState.noticeContent" type="textarea" :rows="4" />
|
||||
<el-input
|
||||
v-model="formState.noticeContent"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态">
|
||||
<el-select v-model="formState.status">
|
||||
<el-option value="0" label="正常" />
|
||||
<el-option value="1" label="停用" />
|
||||
<el-option
|
||||
value="0"
|
||||
label="正常"
|
||||
/>
|
||||
<el-option
|
||||
value="1"
|
||||
label="停用"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="modalVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleModalOk">确定</el-button>
|
||||
<el-button @click="modalVisible = false">
|
||||
取消
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="handleModalOk"
|
||||
>
|
||||
确定
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
@@ -103,10 +174,12 @@ const handleDelete = async (row: any) => {
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
})
|
||||
await request.delete(`/notices/${row.id}`)
|
||||
await request.delete(`/notice/${row.id}`)
|
||||
ElMessage.success('删除成功')
|
||||
fetchData()
|
||||
} catch {}
|
||||
} catch (error) {
|
||||
console.error('删除通知失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const handleModalOk = async () => {
|
||||
@@ -127,7 +200,7 @@ const handleModalOk = async () => {
|
||||
onMounted(() => fetchData())
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
<style scoped lang="css">
|
||||
.notice-management .card-title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
@@ -3,7 +3,10 @@
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="6">
|
||||
<el-card v-loading="loading">
|
||||
<el-statistic title="用户总数" :value="stats.userCount">
|
||||
<el-statistic
|
||||
title="用户总数"
|
||||
:value="stats.userCount"
|
||||
>
|
||||
<template #prefix>
|
||||
<el-icon><User /></el-icon>
|
||||
</template>
|
||||
@@ -12,7 +15,10 @@
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-card v-loading="loading">
|
||||
<el-statistic title="角色总数" :value="stats.roleCount">
|
||||
<el-statistic
|
||||
title="角色总数"
|
||||
:value="stats.roleCount"
|
||||
>
|
||||
<template #prefix>
|
||||
<el-icon><UserFilled /></el-icon>
|
||||
</template>
|
||||
@@ -21,7 +27,10 @@
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-card v-loading="loading">
|
||||
<el-statistic title="今日登录" :value="stats.todayLogin">
|
||||
<el-statistic
|
||||
title="今日登录"
|
||||
:value="stats.todayLogin"
|
||||
>
|
||||
<template #prefix>
|
||||
<el-icon><ArrowRight /></el-icon>
|
||||
</template>
|
||||
@@ -30,7 +39,10 @@
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-card v-loading="loading">
|
||||
<el-statistic title="操作日志" :value="stats.operationLog">
|
||||
<el-statistic
|
||||
title="操作日志"
|
||||
:value="stats.operationLog"
|
||||
>
|
||||
<template #prefix>
|
||||
<el-icon><Document /></el-icon>
|
||||
</template>
|
||||
@@ -38,9 +50,15 @@
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="16" style="margin-top: 16px">
|
||||
<el-row
|
||||
:gutter="16"
|
||||
style="margin-top: 16px"
|
||||
>
|
||||
<el-col :span="12">
|
||||
<el-card title="最近登录" v-loading="loading">
|
||||
<el-card
|
||||
v-loading="loading"
|
||||
title="最近登录"
|
||||
>
|
||||
<el-timeline>
|
||||
<el-timeline-item
|
||||
v-for="item in recentLogins"
|
||||
@@ -54,12 +72,26 @@
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-card title="系统信息" v-loading="loading">
|
||||
<el-descriptions :column="1" border>
|
||||
<el-descriptions-item label="系统版本">{{ systemInfo.version }}</el-descriptions-item>
|
||||
<el-descriptions-item label="Java版本">{{ systemInfo.javaVersion }}</el-descriptions-item>
|
||||
<el-descriptions-item label="前端框架">{{ systemInfo.frontendFramework }}</el-descriptions-item>
|
||||
<el-descriptions-item label="数据库">{{ systemInfo.database }}</el-descriptions-item>
|
||||
<el-card
|
||||
v-loading="loading"
|
||||
title="系统信息"
|
||||
>
|
||||
<el-descriptions
|
||||
:column="1"
|
||||
border
|
||||
>
|
||||
<el-descriptions-item label="系统版本">
|
||||
{{ systemInfo.version }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="Java版本">
|
||||
{{ systemInfo.javaVersion }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="前端框架">
|
||||
{{ systemInfo.frontendFramework }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="数据库">
|
||||
{{ systemInfo.database }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-card>
|
||||
</el-col>
|
||||
@@ -127,7 +159,7 @@ onMounted(() => {
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
<style scoped lang="css">
|
||||
.dashboard {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
@@ -6,25 +6,38 @@
|
||||
</template>
|
||||
<el-form
|
||||
:model="formState"
|
||||
@submit.prevent="onFinish"
|
||||
label-position="top"
|
||||
@submit.prevent="onFinish"
|
||||
>
|
||||
<el-form-item
|
||||
label="用户名"
|
||||
prop="username"
|
||||
:rules="[{ required: true, message: '请输入用户名', trigger: 'blur' }]"
|
||||
>
|
||||
<el-input v-model="formState.username" placeholder="请输入用户名" />
|
||||
<el-input
|
||||
v-model="formState.username"
|
||||
placeholder="请输入用户名"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
label="密码"
|
||||
prop="password"
|
||||
:rules="[{ required: true, message: '请输入密码', trigger: 'blur' }]"
|
||||
>
|
||||
<el-input v-model="formState.password" type="password" placeholder="请输入密码" show-password />
|
||||
<el-input
|
||||
v-model="formState.password"
|
||||
type="password"
|
||||
placeholder="请输入密码"
|
||||
show-password
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" native-type="submit" :loading="loading" style="width: 100%">
|
||||
<el-button
|
||||
type="primary"
|
||||
native-type="submit"
|
||||
:loading="loading"
|
||||
style="width: 100%"
|
||||
>
|
||||
登录
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
@@ -63,13 +76,13 @@ const onFinish = async () => {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
<style scoped lang="css">
|
||||
.login-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
background: var(--el-color-primary-light-9);
|
||||
|
||||
.login-card {
|
||||
width: 400px;
|
||||
|
||||
@@ -4,56 +4,131 @@
|
||||
<template #header>
|
||||
<div class="card-title">
|
||||
<span>菜单管理</span>
|
||||
<el-button type="primary" @click="handleAdd">新增菜单</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="handleAdd"
|
||||
>
|
||||
新增菜单
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
<el-table :data="dataSource" v-loading="loading" :pagination="false" row-key="id" style="width: 100%">
|
||||
<el-table-column prop="menuName" label="菜单名称" />
|
||||
<el-table-column label="菜单类型" width="100">
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="dataSource"
|
||||
:pagination="false"
|
||||
row-key="id"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column
|
||||
prop="menuName"
|
||||
label="菜单名称"
|
||||
/>
|
||||
<el-table-column
|
||||
label="菜单类型"
|
||||
width="100"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="row.menuType === 'M' ? '' : row.menuType === 'C' ? 'success' : 'warning'">
|
||||
{{ row.menuType === 'M' ? '目录' : row.menuType === 'C' ? '菜单' : '按钮' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="perms" label="权限标识" />
|
||||
<el-table-column prop="component" label="组件" />
|
||||
<el-table-column prop="orderNum" label="排序" width="80" />
|
||||
<el-table-column label="状态" width="80">
|
||||
<el-table-column
|
||||
prop="perms"
|
||||
label="权限标识"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="component"
|
||||
label="组件"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="orderNum"
|
||||
label="排序"
|
||||
width="80"
|
||||
/>
|
||||
<el-table-column
|
||||
label="状态"
|
||||
width="80"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="row.status === '0' ? 'success' : 'danger'">
|
||||
{{ row.status === '0' ? '显示' : '隐藏' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="150">
|
||||
<el-table-column
|
||||
label="操作"
|
||||
width="150"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" link size="small" @click="handleEdit(row)">编辑</el-button>
|
||||
<el-button type="danger" link size="small" @click="handleDelete(row)">删除</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
size="small"
|
||||
@click="handleEdit(row)"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
type="danger"
|
||||
link
|
||||
size="small"
|
||||
@click="handleDelete(row)"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
|
||||
<el-dialog v-model="modalVisible" :title="modalTitle" width="500px">
|
||||
<el-form :model="formState" label-width="100px">
|
||||
<el-dialog
|
||||
v-model="modalVisible"
|
||||
:title="modalTitle"
|
||||
width="500px"
|
||||
>
|
||||
<el-form
|
||||
:model="formState"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item label="菜单名称">
|
||||
<el-input v-model="formState.menuName" />
|
||||
</el-form-item>
|
||||
<el-form-item label="父级菜单">
|
||||
<el-tree-select v-model="formState.parentId" :data="menuTree" placeholder="请选择父级菜单" clearable check-strictly />
|
||||
<el-tree-select
|
||||
v-model="formState.parentId"
|
||||
:data="menuTree"
|
||||
placeholder="请选择父级菜单"
|
||||
clearable
|
||||
check-strictly
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="菜单类型">
|
||||
<el-select v-model="formState.menuType">
|
||||
<el-option value="M" label="目录" />
|
||||
<el-option value="C" label="菜单" />
|
||||
<el-option value="F" label="按钮" />
|
||||
<el-option
|
||||
value="M"
|
||||
label="目录"
|
||||
/>
|
||||
<el-option
|
||||
value="C"
|
||||
label="菜单"
|
||||
/>
|
||||
<el-option
|
||||
value="F"
|
||||
label="按钮"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="路由地址" v-if="formState.menuType !== 'F'">
|
||||
<el-form-item
|
||||
v-if="formState.menuType !== 'F'"
|
||||
label="路由地址"
|
||||
>
|
||||
<el-input v-model="formState.perms" />
|
||||
</el-form-item>
|
||||
<el-form-item label="组件路径" v-if="formState.menuType === 'C'">
|
||||
<el-form-item
|
||||
v-if="formState.menuType === 'C'"
|
||||
label="组件路径"
|
||||
>
|
||||
<el-input v-model="formState.component" />
|
||||
</el-form-item>
|
||||
<el-form-item label="排序">
|
||||
@@ -61,14 +136,27 @@
|
||||
</el-form-item>
|
||||
<el-form-item label="状态">
|
||||
<el-select v-model="formState.status">
|
||||
<el-option value="0" label="显示" />
|
||||
<el-option value="1" label="隐藏" />
|
||||
<el-option
|
||||
value="0"
|
||||
label="显示"
|
||||
/>
|
||||
<el-option
|
||||
value="1"
|
||||
label="隐藏"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="modalVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleModalOk">确定</el-button>
|
||||
<el-button @click="modalVisible = false">
|
||||
取消
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="handleModalOk"
|
||||
>
|
||||
确定
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
@@ -125,7 +213,9 @@ const handleDelete = async (row: any) => {
|
||||
await request.delete(`/menus/${row.id}`)
|
||||
ElMessage.success('删除成功')
|
||||
fetchData()
|
||||
} catch {}
|
||||
} catch (error) {
|
||||
console.error('删除菜单失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const handleModalOk = async () => {
|
||||
@@ -146,7 +236,7 @@ const handleModalOk = async () => {
|
||||
onMounted(() => fetchData())
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
<style scoped lang="css">
|
||||
.menu-management .card-title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
@@ -16,16 +16,47 @@
|
||||
<el-icon><Search /></el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
<el-button type="primary" @click="handleSearch">搜索</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="handleSearch"
|
||||
>
|
||||
搜索
|
||||
</el-button>
|
||||
</div>
|
||||
<el-button type="primary" @click="handleAdd">新增角色</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="handleAdd"
|
||||
>
|
||||
新增角色
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
<el-table :data="dataSource" v-loading="loading" style="width: 100%" @sort-change="handleSortChange">
|
||||
<el-table-column prop="id" label="ID" sortable="custom" />
|
||||
<el-table-column prop="roleName" label="角色名称" sortable="custom" />
|
||||
<el-table-column prop="roleKey" label="角色标识" sortable="custom" />
|
||||
<el-table-column prop="roleSort" label="排序" sortable="custom" />
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="dataSource"
|
||||
style="width: 100%"
|
||||
@sort-change="handleSortChange"
|
||||
>
|
||||
<el-table-column
|
||||
prop="id"
|
||||
label="ID"
|
||||
sortable="custom"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="roleName"
|
||||
label="角色名称"
|
||||
sortable="custom"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="roleKey"
|
||||
label="角色标识"
|
||||
sortable="custom"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="roleSort"
|
||||
label="排序"
|
||||
sortable="custom"
|
||||
/>
|
||||
<el-table-column label="状态">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="row.status === '0' ? 'success' : 'danger'">
|
||||
@@ -33,11 +64,30 @@
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createdAt" label="创建时间" sortable="custom" />
|
||||
<el-table-column label="操作" width="200">
|
||||
<el-table-column
|
||||
prop="createdAt"
|
||||
label="创建时间"
|
||||
sortable="custom"
|
||||
/>
|
||||
<el-table-column
|
||||
label="操作"
|
||||
width="200"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" link @click="handleEdit(row)">编辑</el-button>
|
||||
<el-button type="danger" link @click="handleDelete(row)">删除</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
@click="handleEdit(row)"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
type="danger"
|
||||
link
|
||||
@click="handleDelete(row)"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -46,15 +96,22 @@
|
||||
v-model:page-size="pagination.pageSize"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
:total="pagination.total"
|
||||
@current-change="handleTableChange"
|
||||
@size-change="handleSizeChange"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
style="margin-top: 16px; justify-content: flex-end"
|
||||
@current-change="handleTableChange"
|
||||
@size-change="handleSizeChange"
|
||||
/>
|
||||
</el-card>
|
||||
|
||||
<el-dialog v-model="modalVisible" :title="modalTitle" width="500px">
|
||||
<el-form :model="formState" label-width="80px">
|
||||
<el-dialog
|
||||
v-model="modalVisible"
|
||||
:title="modalTitle"
|
||||
width="500px"
|
||||
>
|
||||
<el-form
|
||||
:model="formState"
|
||||
label-width="80px"
|
||||
>
|
||||
<el-form-item label="角色名称">
|
||||
<el-input v-model="formState.roleName" />
|
||||
</el-form-item>
|
||||
@@ -66,14 +123,27 @@
|
||||
</el-form-item>
|
||||
<el-form-item label="状态">
|
||||
<el-select v-model="formState.status">
|
||||
<el-option value="0" label="正常" />
|
||||
<el-option value="1" label="禁用" />
|
||||
<el-option
|
||||
value="0"
|
||||
label="正常"
|
||||
/>
|
||||
<el-option
|
||||
value="1"
|
||||
label="禁用"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="modalVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleModalOk">确定</el-button>
|
||||
<el-button @click="modalVisible = false">
|
||||
取消
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="handleModalOk"
|
||||
>
|
||||
确定
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
@@ -164,7 +234,9 @@ const handleDelete = async (row: any) => {
|
||||
await request.delete(`/roles/${row.id}`)
|
||||
ElMessage.success('删除成功')
|
||||
fetchData()
|
||||
} catch {}
|
||||
} catch (error) {
|
||||
console.error('删除角色失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const handleModalOk = async () => {
|
||||
@@ -185,7 +257,7 @@ const handleModalOk = async () => {
|
||||
onMounted(() => fetchData())
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
<style scoped lang="css">
|
||||
.role-management {
|
||||
.card-header {
|
||||
display: flex;
|
||||
|
||||
@@ -16,33 +16,82 @@
|
||||
<el-icon><Search /></el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
<el-button type="primary" @click="handleSearch">搜索</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="handleSearch"
|
||||
>
|
||||
搜索
|
||||
</el-button>
|
||||
</div>
|
||||
<el-button type="primary" @click="handleAdd">新增用户</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="handleAdd"
|
||||
>
|
||||
新增用户
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
<el-table
|
||||
:data="dataSource"
|
||||
v-loading="loading"
|
||||
:data="dataSource"
|
||||
style="width: 100%"
|
||||
@sort-change="handleSortChange"
|
||||
>
|
||||
<el-table-column prop="id" label="ID" width="80" sortable="custom" />
|
||||
<el-table-column prop="username" label="用户名" sortable="custom" />
|
||||
<el-table-column prop="email" label="邮箱" sortable="custom" />
|
||||
<el-table-column prop="phone" label="手机号" sortable="custom" />
|
||||
<el-table-column label="状态" width="100">
|
||||
<el-table-column
|
||||
prop="id"
|
||||
label="ID"
|
||||
width="80"
|
||||
sortable="custom"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="username"
|
||||
label="用户名"
|
||||
sortable="custom"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="email"
|
||||
label="邮箱"
|
||||
sortable="custom"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="phone"
|
||||
label="手机号"
|
||||
sortable="custom"
|
||||
/>
|
||||
<el-table-column
|
||||
label="状态"
|
||||
width="100"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="row.status === '0' ? 'success' : 'danger'">
|
||||
{{ row.status === '0' ? '正常' : '禁用' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createdAt" label="创建时间" sortable="custom" />
|
||||
<el-table-column label="操作" width="200">
|
||||
<el-table-column
|
||||
prop="createdAt"
|
||||
label="创建时间"
|
||||
sortable="custom"
|
||||
/>
|
||||
<el-table-column
|
||||
label="操作"
|
||||
width="200"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" link @click="handleEdit(row)">编辑</el-button>
|
||||
<el-button type="danger" link @click="handleDelete(row)">删除</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
@click="handleEdit(row)"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
type="danger"
|
||||
link
|
||||
@click="handleDelete(row)"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -51,10 +100,10 @@
|
||||
v-model:page-size="pagination.pageSize"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
:total="pagination.total"
|
||||
@current-change="handleTableChange"
|
||||
@size-change="handleSizeChange"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
style="margin-top: 16px; justify-content: flex-end"
|
||||
@current-change="handleTableChange"
|
||||
@size-change="handleSizeChange"
|
||||
/>
|
||||
</el-card>
|
||||
|
||||
@@ -78,14 +127,27 @@
|
||||
</el-form-item>
|
||||
<el-form-item label="状态">
|
||||
<el-select v-model="formState.status">
|
||||
<el-option value="0" label="正常" />
|
||||
<el-option value="1" label="禁用" />
|
||||
<el-option
|
||||
value="0"
|
||||
label="正常"
|
||||
/>
|
||||
<el-option
|
||||
value="1"
|
||||
label="禁用"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="handleModalCancel">取消</el-button>
|
||||
<el-button type="primary" @click="handleModalOk">确定</el-button>
|
||||
<el-button @click="handleModalCancel">
|
||||
取消
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="handleModalOk"
|
||||
>
|
||||
确定
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
@@ -212,7 +274,7 @@ onMounted(() => {
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
<style scoped lang="css">
|
||||
.user-management {
|
||||
.card-header {
|
||||
display: flex;
|
||||
|
||||
Reference in New Issue
Block a user