样式修正,支持配置登录方式、icon等
This commit is contained in:
@@ -5,6 +5,52 @@
|
||||
* @figma https://www.figma.com/design/4aM0yqyoAjtW2jTZcqPAtN
|
||||
*/
|
||||
|
||||
// ============ Element Plus 主题色覆盖 ============
|
||||
:root {
|
||||
--el-color-primary: #C62828;
|
||||
--el-color-primary-light-3: rgba(198, 40, 40, 0.7);
|
||||
--el-color-primary-light-5: rgba(198, 40, 40, 0.5);
|
||||
--el-color-primary-light-7: rgba(198, 40, 40, 0.3);
|
||||
--el-color-primary-light-8: rgba(198, 40, 40, 0.2);
|
||||
--el-color-primary-light-9: rgba(198, 40, 40, 0.1);
|
||||
--el-color-primary-dark-2: #B71C1C;
|
||||
}
|
||||
|
||||
// small按钮保持默认蓝色(不包括link样式)
|
||||
.el-button--primary.el-button--small:not(.is-link) {
|
||||
background-color: #409eff !important;
|
||||
border-color: #409eff !important;
|
||||
color: #ffffff !important;
|
||||
transition: all 0.2s;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: #66b1ff !important;
|
||||
border-color: #66b1ff !important;
|
||||
color: #ffffff !important;
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: #3a8ee6 !important;
|
||||
border-color: #3a8ee6 !important;
|
||||
color: #ffffff !important;
|
||||
}
|
||||
}
|
||||
|
||||
// link按钮保持蓝色
|
||||
.el-button--primary.is-link {
|
||||
color: #409eff !important;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: #66b1ff !important;
|
||||
}
|
||||
|
||||
&:active {
|
||||
color: #3a8ee6 !important;
|
||||
}
|
||||
}
|
||||
|
||||
// ============ 字体声明 ============
|
||||
@font-face {
|
||||
font-family: 'Source Han Sans SC';
|
||||
@@ -249,7 +295,7 @@ $spacing-xxl: 24px;
|
||||
border-radius: $border-radius-large;
|
||||
|
||||
// Element Plus 分页组件自定义样式
|
||||
:deep(.el-pagination) {
|
||||
.el-pagination {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: $spacing-sm;
|
||||
@@ -271,29 +317,37 @@ $spacing-xxl: 24px;
|
||||
|
||||
.el-select {
|
||||
.el-select__wrapper {
|
||||
background: $color-bg-secondary;
|
||||
border: none;
|
||||
border-radius: $border-radius-small;
|
||||
padding: $spacing-xs $spacing-md;
|
||||
background: $color-bg-white;
|
||||
border: 1px solid #E5E6EB;
|
||||
border-radius: 4px;
|
||||
padding: 4px 8px;
|
||||
min-height: 32px;
|
||||
box-shadow: none;
|
||||
transition: all 0.2s;
|
||||
|
||||
.el-select__selected-item {
|
||||
font-family: $font-family-cn;
|
||||
font-size: $font-size-base;
|
||||
font-family: $font-family-en;
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
line-height: $line-height-base;
|
||||
line-height: 22px;
|
||||
color: $color-text-primary;
|
||||
}
|
||||
|
||||
.el-select__suffix {
|
||||
.el-icon {
|
||||
color: $color-text-secondary;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: darken($color-bg-secondary, 3%);
|
||||
border-color: #C62828;
|
||||
background: $color-bg-white;
|
||||
}
|
||||
|
||||
&.is-focused {
|
||||
border-color: #C62828;
|
||||
box-shadow: 0 0 0 2px rgba(198, 40, 40, 0.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -315,10 +369,10 @@ $spacing-xxl: 24px;
|
||||
}
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
background: rgba($color-primary, 0.08);
|
||||
background: rgba(#C62828, 0.08);
|
||||
|
||||
.el-icon {
|
||||
color: $color-primary;
|
||||
color: #C62828;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,8 +393,8 @@ $spacing-xxl: 24px;
|
||||
gap: $spacing-xs;
|
||||
|
||||
li {
|
||||
background: transparent;
|
||||
border: none;
|
||||
background: transparent !important;
|
||||
border: none !important;
|
||||
border-radius: $border-radius-small;
|
||||
padding: $spacing-xs;
|
||||
min-width: 32px;
|
||||
@@ -349,32 +403,32 @@ $spacing-xxl: 24px;
|
||||
font-family: $font-family-en;
|
||||
font-size: $font-size-base;
|
||||
font-weight: 600;
|
||||
color: $color-text-secondary;
|
||||
color: $color-text-secondary !important;
|
||||
text-align: center;
|
||||
margin: 0;
|
||||
|
||||
&:hover:not(.is-active):not(.is-disabled) {
|
||||
background: rgba($color-primary, 0.08);
|
||||
color: $color-primary;
|
||||
background: rgba(#C62828, 0.08) !important;
|
||||
color: #C62828 !important;
|
||||
}
|
||||
|
||||
&.is-active {
|
||||
background: $color-primary;
|
||||
color: $color-bg-white;
|
||||
background: #C62828 !important;
|
||||
color: #FFFFFF !important;
|
||||
}
|
||||
|
||||
&.is-disabled {
|
||||
color: $color-text-disabled;
|
||||
color: $color-text-disabled !important;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
// 更多页省略号
|
||||
&.more {
|
||||
background: transparent;
|
||||
color: $color-text-secondary;
|
||||
background: transparent !important;
|
||||
color: $color-text-secondary !important;
|
||||
|
||||
&:hover {
|
||||
color: $color-primary;
|
||||
color: #C62828 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -399,17 +453,17 @@ $spacing-xxl: 24px;
|
||||
.el-input__inner {
|
||||
font-family: $font-family-en;
|
||||
font-size: $font-size-base;
|
||||
font-weight: 600;
|
||||
font-weight: 400;
|
||||
color: $color-text-primary;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
border-color: $color-primary;
|
||||
border-color: #C62828;
|
||||
}
|
||||
|
||||
&.is-focus {
|
||||
border-color: $color-primary;
|
||||
border-color: #C62828;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,4 +31,10 @@ function changeHome(){
|
||||
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.change-home{
|
||||
.change-home-item{
|
||||
cursor: pointer;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -3,8 +3,8 @@
|
||||
<div class="nav-container">
|
||||
<!-- Logo区域 -->
|
||||
<div class="nav-logo">
|
||||
<img src="@/assets/imgs/logo-icon.svg" alt="Logo" class="logo-icon" />
|
||||
<span class="logo-text">红色思政学习平台</span>
|
||||
<img :src="homeLogoUrl" alt="Logo" class="logo-icon" />
|
||||
<span class="logo-text">{{ systemName }}</span>
|
||||
</div>
|
||||
|
||||
<!-- 导航菜单 -->
|
||||
@@ -81,6 +81,10 @@ const router = useRouter();
|
||||
const route = useRoute();
|
||||
const store = useStore();
|
||||
|
||||
// 获取系统配置
|
||||
const systemName = computed(() => store.getters['system/systemName']);
|
||||
const homeLogoUrl = computed(() => store.getters['system/homeLogoUrl']);
|
||||
|
||||
const activeDropdown = ref<string | null>(null);
|
||||
const searchKeyword = ref('');
|
||||
const dropdownPositions = ref<Record<string, { left: number; top: number; width: number }>>({});
|
||||
|
||||
@@ -9,10 +9,10 @@
|
||||
<!-- Logo区域 -->
|
||||
<div class="sidebar-header">
|
||||
<div class="logo-container">
|
||||
<img src="@/assets/imgs/logo-icon.svg" alt="Logo" class="logo-icon" />
|
||||
<img :src="adminLogoUrl" alt="Logo" class="logo-icon" />
|
||||
<div class="logo-text">
|
||||
<div class="logo-title">管理后台</div>
|
||||
<div class="logo-subtitle">红色思政平台</div>
|
||||
<div class="logo-subtitle">{{ systemShortName }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -26,7 +26,7 @@
|
||||
<!-- 页面内容 -->
|
||||
<main class="main-wrapper">
|
||||
<nav class="top-nav">
|
||||
<UserDropdown :userinfo="user" @logout="handleLogout" />
|
||||
<UserDropdown :userinfo="userInfo" @logout="handleLogout" />
|
||||
</nav>
|
||||
<div class="main-content">
|
||||
<router-view />
|
||||
@@ -56,7 +56,11 @@ const route = useRoute();
|
||||
const router = useRouter();
|
||||
const store = useStore();
|
||||
|
||||
const user = computed(() => store.getters['auth/user']);
|
||||
const userInfo = computed(() => store.getters['auth/userinfo']);
|
||||
|
||||
// 获取系统配置
|
||||
const systemShortName = computed(() => store.getters['system/systemShortName']);
|
||||
const adminLogoUrl = computed(() => store.getters['system/adminLogoUrl']);
|
||||
|
||||
// 获取所有菜单
|
||||
const allMenus = computed(() => store.getters['auth/menuTree']);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { createApp } from "vue";
|
||||
import ElementPlus from "element-plus";
|
||||
import "element-plus/dist/index.css";
|
||||
import zhCn from "element-plus/es/locale/lang/zh-cn";
|
||||
import App from "./App.vue";
|
||||
import "./registerServiceWorker";
|
||||
import router from "./router";
|
||||
@@ -19,7 +20,7 @@ async function initApp() {
|
||||
const app = createApp(App);
|
||||
|
||||
// 使用插件
|
||||
app.use(ElementPlus);
|
||||
app.use(ElementPlus, { locale: zhCn });
|
||||
app.use(store);
|
||||
|
||||
// 加载系统基础信息(Logo、系统名称、登录开关等)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { configApi } from '@/apis/system';
|
||||
import type { SystemBaseInfo } from '@/types/system/baseinfo';
|
||||
import { FILE_DOWNLOAD_URL } from '@/config';
|
||||
import logoIcon from '@/assets/imgs/logo-icon.svg';
|
||||
|
||||
interface SystemState {
|
||||
baseInfo: SystemBaseInfo | null;
|
||||
@@ -30,22 +31,22 @@ export default {
|
||||
// Logo URL(自动拼接fileId,为空时使用默认图片)
|
||||
loginLogoUrl: (state: SystemState) => {
|
||||
const fileId = state.baseInfo?.loginLogo;
|
||||
return fileId ? `${FILE_DOWNLOAD_URL}/${fileId}` : '/logo-icon.svg';
|
||||
return (fileId && fileId.trim()) ? `${FILE_DOWNLOAD_URL}${fileId}` : logoIcon;
|
||||
},
|
||||
|
||||
homeLogoUrl: (state: SystemState) => {
|
||||
const fileId = state.baseInfo?.homeLogo;
|
||||
return fileId ? `${FILE_DOWNLOAD_URL}/${fileId}` : '/logo-icon.svg';
|
||||
return (fileId && fileId.trim()) ? `${FILE_DOWNLOAD_URL}${fileId}` : logoIcon;
|
||||
},
|
||||
|
||||
adminLogoUrl: (state: SystemState) => {
|
||||
const fileId = state.baseInfo?.adminLogo;
|
||||
return fileId ? `${FILE_DOWNLOAD_URL}/${fileId}` : '/logo-icon.svg';
|
||||
return (fileId && fileId.trim()) ? `${FILE_DOWNLOAD_URL}${fileId}` : logoIcon;
|
||||
},
|
||||
|
||||
faviconUrl: (state: SystemState) => {
|
||||
const fileId = state.baseInfo?.favicon;
|
||||
return fileId ? `${FILE_DOWNLOAD_URL}/${fileId}` : '/favicon.ico';
|
||||
return (fileId && fileId.trim()) ? `${FILE_DOWNLOAD_URL}${fileId}` : '/favicon.ico';
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -155,13 +155,13 @@ function isActive(menu: RouteRecordRaw): boolean {
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: #165DFF;
|
||||
color: #C62828;
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: #165DFF;
|
||||
color: #C62828;
|
||||
font-weight: 500;
|
||||
border-bottom-color: #165DFF;
|
||||
border-bottom-color: #C62828;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,16 +28,17 @@
|
||||
|
||||
<el-empty v-if="!loading && knowledgeCards.length === 0" description="暂无知识库" />
|
||||
|
||||
<el-pagination
|
||||
v-if="total >= 0"
|
||||
:current-page="pageParam.pageNumber"
|
||||
:page-size="pageParam.pageSize"
|
||||
:total="total"
|
||||
:page-sizes="[9, 18, 36]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
@current-change="handlePageChange"
|
||||
@size-change="handleSizeChange"
|
||||
/>
|
||||
<div class="pagination-container" v-if="total >= 0">
|
||||
<el-pagination
|
||||
:current-page="pageParam.pageNumber"
|
||||
:page-size="pageParam.pageSize"
|
||||
:total="total"
|
||||
:page-sizes="[9, 18, 36]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
@current-change="handlePageChange"
|
||||
@size-change="handleSizeChange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 层级2: 知识库详情(覆盖在列表上方) -->
|
||||
|
||||
@@ -1231,13 +1231,6 @@ onMounted(() => {
|
||||
}
|
||||
}
|
||||
|
||||
// 分页组件
|
||||
// .pagination-container {
|
||||
// margin-top: 24px;
|
||||
// display: flex;
|
||||
// justify-content: center;
|
||||
// padding: 20px 0;
|
||||
// }
|
||||
|
||||
// ==================== 下拉选择器样式 ====================
|
||||
.select-container {
|
||||
|
||||
@@ -70,9 +70,8 @@
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
|
||||
<div class="pagination-container">
|
||||
<el-pagination
|
||||
class="pagination-container"
|
||||
v-model:current-page="pageParam.pageNumber"
|
||||
v-model:page-size="pageParam.pageSize"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
@@ -81,6 +80,7 @@
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -361,11 +361,6 @@ onMounted(() => {
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
|
||||
//.pagination-container {
|
||||
// display: flex;
|
||||
// justify-content: center;
|
||||
// margin-top: 20px;
|
||||
// }
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
|
||||
@@ -753,12 +753,6 @@ onMounted(() => {
|
||||
}
|
||||
}
|
||||
|
||||
.pagination-container {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.cron-examples {
|
||||
div {
|
||||
padding: 6px 0;
|
||||
|
||||
@@ -526,11 +526,6 @@ function handleSizeChange(size: number) {
|
||||
|
||||
// el-table和el-button会自动处理样式和交互
|
||||
|
||||
.pagination-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -200,16 +200,18 @@
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<el-pagination
|
||||
v-model:current-page="pagination.page"
|
||||
v-model:page-size="pagination.size"
|
||||
:total="pagination.total"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
@size-change="loadMessages"
|
||||
@current-change="loadMessages"
|
||||
style="margin-top: 20px; justify-content: flex-end"
|
||||
/>
|
||||
<div class="pagination-container" v-if="pagination.total >= 0">
|
||||
<el-pagination
|
||||
v-model:current-page="pagination.page"
|
||||
v-model:page-size="pagination.size"
|
||||
:total="pagination.total"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
@size-change="loadMessages"
|
||||
@current-change="loadMessages"
|
||||
style="margin-top: 20px; justify-content: flex-end"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<!-- 创建/编辑对话框 -->
|
||||
|
||||
@@ -44,15 +44,16 @@
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<el-pagination
|
||||
class="pagination-container"
|
||||
v-model:current-page="pageParam.pageNumber"
|
||||
v-model:page-size="pageParam.pageSize"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
<div class="pagination-container">
|
||||
<el-pagination
|
||||
v-model:current-page="pageParam.pageNumber"
|
||||
v-model:page-size="pageParam.pageSize"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 文章查看弹窗 -->
|
||||
<ArticleShowView
|
||||
|
||||
@@ -768,14 +768,6 @@ onMounted(() => {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 分页容器
|
||||
.pagination-container {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
// 详情对话框样式
|
||||
.detail-content {
|
||||
max-height: 70vh;
|
||||
|
||||
@@ -111,19 +111,16 @@
|
||||
:label="item.configName || item.configKey"
|
||||
:prop="item.configKey"
|
||||
>
|
||||
<el-upload
|
||||
:action="uploadUrl"
|
||||
:headers="uploadHeaders"
|
||||
:show-file-list="true"
|
||||
:limit="1"
|
||||
list-type="picture-card"
|
||||
:on-success="(response: any) => handleUploadSuccess(response, group.groupKey, item.configKey)"
|
||||
:on-remove="() => handleRemove(group.groupKey, item.configKey)"
|
||||
:file-list="getFileList(group.groupKey, item.configKey)"
|
||||
>
|
||||
<el-icon><Plus /></el-icon>
|
||||
</el-upload>
|
||||
<span v-if="item.remark" class="form-item-remark">{{ item.remark }}</span>
|
||||
<FileUpload
|
||||
list-type="cover"
|
||||
:cover-url="configData[group.groupKey][item.configKey]"
|
||||
@update:cover-url="(url) => handleCoverUpdate(url, group.groupKey, item.configKey)"
|
||||
accept="image/*"
|
||||
:max-size="5"
|
||||
module="system"
|
||||
:as-dialog="false"
|
||||
:tip="item.remark || '点击上传图片,支持jpg、png格式'"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
@@ -146,14 +143,12 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted, computed } from 'vue';
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import { AdminLayout } from '@/views/admin';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { Plus } from '@element-plus/icons-vue';
|
||||
import { configApi } from '@/apis/system';
|
||||
import type { ConfigItem } from '@/types/system/config';
|
||||
import { APP_CONFIG, FILE_DOWNLOAD_URL } from '@/config';
|
||||
import { useStore } from 'vuex';
|
||||
import FileUpload from '@/components/file/FileUpload.vue';
|
||||
|
||||
defineOptions({
|
||||
name: 'SystemConfigView'
|
||||
@@ -170,13 +165,6 @@ interface ConfigGroup {
|
||||
const loading = ref(false);
|
||||
const saving = ref(false);
|
||||
const activeTab = ref('');
|
||||
const store = useStore();
|
||||
|
||||
// 上传配置
|
||||
const uploadUrl = APP_CONFIG.file.uploadUrl;
|
||||
const uploadHeaders = computed(() => ({
|
||||
Authorization: `Bearer ${store.state.auth.token}`
|
||||
}));
|
||||
|
||||
// 配置分组列表
|
||||
const configGroups = ref<ConfigGroup[]>([]);
|
||||
@@ -364,38 +352,10 @@ async function loadConfigs() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件列表(用于显示已上传的图片)
|
||||
* 处理封面URL更新
|
||||
*/
|
||||
function getFileList(groupKey: string, configKey: string): any[] {
|
||||
const fileId = configData[groupKey]?.[configKey];
|
||||
if (fileId) {
|
||||
return [{
|
||||
name: 'image',
|
||||
url: `${FILE_DOWNLOAD_URL}${fileId}`
|
||||
}];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理上传成功
|
||||
*/
|
||||
function handleUploadSuccess(response: any, groupKey: string, configKey: string) {
|
||||
if (response.success && response.data) {
|
||||
// 后端返回的是fileId
|
||||
configData[groupKey][configKey] = response.data;
|
||||
ElMessage.success('图片上传成功');
|
||||
} else {
|
||||
ElMessage.error(response.message || '图片上传失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理删除图片
|
||||
*/
|
||||
function handleRemove(groupKey: string, configKey: string) {
|
||||
configData[groupKey][configKey] = '';
|
||||
ElMessage.success('图片已删除');
|
||||
function handleCoverUpdate(url: string, groupKey: string, configKey: string) {
|
||||
configData[groupKey][configKey] = url;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -603,11 +603,6 @@ function handleSizeChange(size: number) {
|
||||
}
|
||||
}
|
||||
|
||||
.pagination-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
.tag-container {
|
||||
display: flex;
|
||||
|
||||
@@ -130,18 +130,18 @@ onMounted(() => {
|
||||
color: #606266;
|
||||
|
||||
&:hover {
|
||||
color: #409eff;
|
||||
color: #C62828;
|
||||
}
|
||||
|
||||
&.is-active {
|
||||
color: #409eff;
|
||||
color: #C62828;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.el-tabs__active-bar {
|
||||
height: 3px;
|
||||
background: linear-gradient(90deg, #409eff 0%, #66b1ff 100%);
|
||||
background: linear-gradient(90deg, #C62828 0%, #66b1ff 100%);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,7 +184,7 @@ onMounted(() => {
|
||||
|
||||
&:hover {
|
||||
background: linear-gradient(90deg, #e3f2fd 0%, #f5f5f5 100%);
|
||||
border-left-color: #409eff;
|
||||
border-left-color: #C62828;
|
||||
transform: translateX(4px);
|
||||
box-shadow: 0 4px 12px rgba(64, 158, 255, 0.15);
|
||||
|
||||
@@ -227,13 +227,13 @@ onMounted(() => {
|
||||
white-space: nowrap;
|
||||
|
||||
&:hover {
|
||||
color: #409eff;
|
||||
color: #C62828;
|
||||
}
|
||||
}
|
||||
|
||||
.item-arrow {
|
||||
font-size: 16px;
|
||||
color: #409eff;
|
||||
color: #C62828;
|
||||
opacity: 0;
|
||||
transition: all 0.3s ease;
|
||||
flex-shrink: 0;
|
||||
|
||||
@@ -104,17 +104,19 @@
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<el-pagination
|
||||
v-if="total > 0"
|
||||
v-model:current-page="currentPage"
|
||||
v-model:page-size="pageSize"
|
||||
:total="total"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
class="pagination"
|
||||
@size-change="handlePageChange"
|
||||
@current-change="handlePageChange"
|
||||
/>
|
||||
<div class="pagination-container" v-if="total >= 0">
|
||||
<el-pagination
|
||||
v-if="total > 0"
|
||||
v-model:current-page="currentPage"
|
||||
v-model:page-size="pageSize"
|
||||
:total="total"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
class="pagination"
|
||||
@size-change="handlePageChange"
|
||||
@current-change="handlePageChange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -20,9 +20,9 @@
|
||||
<div class="login-header">
|
||||
<div class="logo-section">
|
||||
<div class="logo">
|
||||
<img src="@/assets/imgs/logo-icon.svg" alt="Logo" />
|
||||
<img :src="loginLogoUrl" alt="Logo" />
|
||||
</div>
|
||||
<h1 class="platform-title">红色思政学习平台</h1>
|
||||
<h1 class="platform-title">{{ systemName }}</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -194,6 +194,8 @@ const store = useStore();
|
||||
// 获取系统配置
|
||||
const smsLoginEnabled = computed(() => store.getters['system/smsLoginEnabled']);
|
||||
const emailLoginEnabled = computed(() => store.getters['system/emailLoginEnabled']);
|
||||
const systemName = computed(() => store.getters['system/systemName']);
|
||||
const loginLogoUrl = computed(() => store.getters['system/loginLogoUrl']);
|
||||
|
||||
// 是否支持密码找回
|
||||
const canResetPassword = computed(() => smsLoginEnabled.value || emailLoginEnabled.value);
|
||||
@@ -554,16 +556,14 @@ onUnmounted(() => {
|
||||
.logo {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
background: #C62828;
|
||||
border-radius: 6px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 3px;
|
||||
|
||||
img {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,9 +20,9 @@
|
||||
<div class="forgot-password-header">
|
||||
<div class="logo-section">
|
||||
<div class="logo">
|
||||
<img src="@/assets/imgs/logo-icon.svg" alt="Logo" />
|
||||
<img :src="loginLogoUrl" alt="Logo" />
|
||||
</div>
|
||||
<h1 class="platform-title">红色思政学习平台</h1>
|
||||
<h1 class="platform-title">{{ systemName }}</h1>
|
||||
</div>
|
||||
<h2 class="forgot-password-title">找回密码</h2>
|
||||
</div>
|
||||
@@ -193,6 +193,8 @@ const store = useStore();
|
||||
// 获取系统配置
|
||||
const smsLoginEnabled = computed(() => store.getters['system/smsLoginEnabled']);
|
||||
const emailLoginEnabled = computed(() => store.getters['system/emailLoginEnabled']);
|
||||
const systemName = computed(() => store.getters['system/systemName']);
|
||||
const loginLogoUrl = computed(() => store.getters['system/loginLogoUrl']);
|
||||
|
||||
// 是否支持密码找回(至少一种方式启用)
|
||||
const canResetPassword = computed(() => smsLoginEnabled.value || emailLoginEnabled.value);
|
||||
@@ -571,22 +573,21 @@ onUnmounted(() => {
|
||||
.logo-section {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 11px;
|
||||
margin-bottom: 16px;
|
||||
|
||||
.logo {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
background: #C62828;
|
||||
border-radius: 6px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 3px;
|
||||
|
||||
img {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -753,12 +754,6 @@ onUnmounted(() => {
|
||||
text-align: center;
|
||||
margin-bottom: 32px;
|
||||
|
||||
.logo img {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
|
||||
@@ -20,9 +20,9 @@
|
||||
<div class="login-header">
|
||||
<div class="logo-section">
|
||||
<div class="logo">
|
||||
<img src="@/assets/imgs/logo-icon.svg" alt="Logo" />
|
||||
<img :src="loginLogoUrl" alt="Logo" />
|
||||
</div>
|
||||
<h1 class="platform-title">红色思政学习平台</h1>
|
||||
<h1 class="platform-title">{{ systemName }}</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -221,6 +221,8 @@ const store = useStore();
|
||||
// 获取系统配置
|
||||
const smsLoginEnabled = computed(() => store.getters['system/smsLoginEnabled']);
|
||||
const emailLoginEnabled = computed(() => store.getters['system/emailLoginEnabled']);
|
||||
const systemName = computed(() => store.getters['system/systemName']);
|
||||
const loginLogoUrl = computed(() => store.getters['system/loginLogoUrl']);
|
||||
|
||||
// 是否显示验证码登录选项卡
|
||||
const showCaptchaLoginTab = computed(() => smsLoginEnabled.value || emailLoginEnabled.value);
|
||||
@@ -609,16 +611,14 @@ onMounted(() => {
|
||||
.logo {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
background: #C62828;
|
||||
border-radius: 6px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 3px;
|
||||
|
||||
img {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,9 +20,9 @@
|
||||
<div class="login-header">
|
||||
<div class="logo-section">
|
||||
<div class="logo">
|
||||
<img src="@/assets/imgs/logo-icon.svg" alt="Logo" />
|
||||
<img :src="loginLogoUrl" alt="Logo" />
|
||||
</div>
|
||||
<h1 class="platform-title">红色思政学习平台</h1>
|
||||
<h1 class="platform-title">{{ systemName }}</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -221,6 +221,8 @@ const store = useStore();
|
||||
// 获取系统配置(必须先定义,因为后续初始化会用到)
|
||||
const smsLoginEnabled = computed(() => store.getters['system/smsLoginEnabled']);
|
||||
const emailLoginEnabled = computed(() => store.getters['system/emailLoginEnabled']);
|
||||
const systemName = computed(() => store.getters['system/systemName']);
|
||||
const loginLogoUrl = computed(() => store.getters['system/loginLogoUrl']);
|
||||
|
||||
// 登录模式:password-密码登录,captcha-验证码登录
|
||||
const loginMode = ref<'password' | 'captcha'>('password');
|
||||
@@ -612,16 +614,14 @@ onMounted(() => {
|
||||
.logo {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
background: #C62828;
|
||||
border-radius: 6px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 3px;
|
||||
|
||||
img {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,9 +20,9 @@
|
||||
<div class="login-header">
|
||||
<div class="logo-section">
|
||||
<div class="logo">
|
||||
<img src="@/assets/imgs/logo-icon.svg" alt="Logo" />
|
||||
<img :src="loginLogoUrl" alt="Logo" />
|
||||
</div>
|
||||
<h1 class="platform-title">红色思政学习平台</h1>
|
||||
<h1 class="platform-title">{{ systemName }}</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -208,6 +208,8 @@ const store = useStore();
|
||||
// 获取系统配置
|
||||
const smsLoginEnabled = computed(() => store.getters['system/smsLoginEnabled']);
|
||||
const emailLoginEnabled = computed(() => store.getters['system/emailLoginEnabled']);
|
||||
const systemName = computed(() => store.getters['system/systemName']);
|
||||
const loginLogoUrl = computed(() => store.getters['system/loginLogoUrl']);
|
||||
|
||||
// 注册方式
|
||||
const registerType = ref<RegisterType>(RegisterType.USERNAME);
|
||||
@@ -600,16 +602,14 @@ onUnmounted(() => {
|
||||
.logo {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
background: #C62828;
|
||||
border-radius: 6px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 3px;
|
||||
|
||||
img {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,9 +20,9 @@
|
||||
<div class="register-header">
|
||||
<div class="logo-section">
|
||||
<div class="logo">
|
||||
<img src="@/assets/imgs/logo-icon.svg" alt="Logo" />
|
||||
<img :src="loginLogoUrl" alt="Logo" />
|
||||
</div>
|
||||
<h1 class="platform-title">红色思政学习平台</h1>
|
||||
<h1 class="platform-title">{{ systemName }}</h1>
|
||||
</div>
|
||||
<h2 class="register-title">{{ registerTypeTitle }}</h2>
|
||||
|
||||
@@ -215,6 +215,8 @@ const store = useStore();
|
||||
// 获取系统配置
|
||||
const smsLoginEnabled = computed(() => store.getters['system/smsLoginEnabled']);
|
||||
const emailLoginEnabled = computed(() => store.getters['system/emailLoginEnabled']);
|
||||
const systemName = computed(() => store.getters['system/systemName']);
|
||||
const loginLogoUrl = computed(() => store.getters['system/loginLogoUrl']);
|
||||
|
||||
// 注册方式
|
||||
const registerType = ref<RegisterType>(RegisterType.USERNAME);
|
||||
@@ -617,16 +619,14 @@ onUnmounted(() => {
|
||||
.logo {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
background: #C62828;
|
||||
border-radius: 6px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 3px;
|
||||
|
||||
img {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -886,6 +886,10 @@ function getItemStatusType(status?: number): 'info' | 'warning' | 'success' {
|
||||
|
||||
.resource-action {
|
||||
flex-shrink: 0;
|
||||
button {
|
||||
background-color: #C62828;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -747,20 +747,6 @@ async function loadMoreMessages() {
|
||||
}
|
||||
}
|
||||
|
||||
.pagination-container {
|
||||
padding: 12px 0;
|
||||
|
||||
:deep(.el-pagination) {
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
|
||||
.el-pagination__total,
|
||||
.el-pagination__sizes,
|
||||
.el-pagination__jump {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -830,11 +830,6 @@ function goBack() {
|
||||
}
|
||||
}
|
||||
|
||||
// 分页
|
||||
.pagination-container {
|
||||
height: 5%;
|
||||
}
|
||||
|
||||
// 移动端加载更多提示
|
||||
.mobile-load-more {
|
||||
padding: 20px 0;
|
||||
@@ -1051,37 +1046,6 @@ function goBack() {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
// 分页
|
||||
.pagination-container {
|
||||
height: auto;
|
||||
padding: 16px;
|
||||
|
||||
:deep(.el-pagination) {
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
|
||||
.el-pagination__total,
|
||||
.el-pagination__sizes,
|
||||
.el-pagination__jump {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.btn-prev,
|
||||
.btn-next {
|
||||
min-width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
.el-pager li {
|
||||
min-width: 28px;
|
||||
height: 28px;
|
||||
line-height: 28px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -466,7 +466,7 @@ onMounted(() => {
|
||||
|
||||
.title-icon {
|
||||
font-size: 28px;
|
||||
color: #409eff;
|
||||
color: #C62828;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -476,7 +476,7 @@ onMounted(() => {
|
||||
margin: 0;
|
||||
|
||||
.keyword-text {
|
||||
color: #409eff;
|
||||
color: #C62828;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
@@ -558,7 +558,7 @@ onMounted(() => {
|
||||
.stat-value {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #409eff;
|
||||
color: #C62828;
|
||||
}
|
||||
|
||||
.stat-divider {
|
||||
@@ -622,7 +622,7 @@ onMounted(() => {
|
||||
|
||||
.el-icon {
|
||||
font-size: 24px;
|
||||
color: #409eff;
|
||||
color: #C62828;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -696,7 +696,7 @@ onMounted(() => {
|
||||
.view-button {
|
||||
padding: 8px 24px;
|
||||
background: white;
|
||||
color: #409eff;
|
||||
color: #C62828;
|
||||
border-radius: 20px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
|
||||
@@ -392,14 +392,6 @@ defineExpose({
|
||||
margin: 16px;
|
||||
}
|
||||
|
||||
.pagination-container {
|
||||
padding: 20px 30px;
|
||||
border-top: 1px solid #EEEEEE;
|
||||
|
||||
:deep(.el-pagination) {
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
/* 移动端适配 */
|
||||
@media (max-width: 768px) {
|
||||
@@ -436,18 +428,7 @@ defineExpose({
|
||||
-webkit-line-clamp: 2;
|
||||
line-clamp: 2;
|
||||
}
|
||||
|
||||
.pagination-container {
|
||||
padding: 12px 16px;
|
||||
|
||||
:deep(.el-pagination) {
|
||||
.el-pagination__sizes,
|
||||
.el-pagination__total,
|
||||
.el-pagination__jump {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -677,11 +677,6 @@ function getDeadlineStatus(task: TaskItemVO): { show: boolean; text: string; typ
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.pagination-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
/* 移动端适配 */
|
||||
@media (max-width: 768px) {
|
||||
@@ -829,28 +824,5 @@ function getDeadlineStatus(task: TaskItemVO): { show: boolean; text: string; typ
|
||||
}
|
||||
}
|
||||
|
||||
.pagination-container {
|
||||
margin-top: 24px;
|
||||
|
||||
:deep(.el-pagination) {
|
||||
.el-pagination__sizes,
|
||||
.el-pagination__total,
|
||||
.el-pagination__jump {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.el-pager li {
|
||||
min-width: 28px;
|
||||
height: 28px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.btn-prev,
|
||||
.btn-next {
|
||||
min-width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -52,18 +52,17 @@
|
||||
</div>
|
||||
|
||||
<!-- 桌面端分页 -->
|
||||
<el-pagination
|
||||
v-if="!isMobile"
|
||||
class="pagination-container"
|
||||
v-model:current-page="currentPage"
|
||||
v-model:page-size="pageSize"
|
||||
:total="totalElements"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
style="margin-top: 20px; justify-content: center"
|
||||
/>
|
||||
<div v-if="!isMobile" class="pagination-container" style="margin-top: 20px;">
|
||||
<el-pagination
|
||||
v-model:current-page="currentPage"
|
||||
v-model:page-size="pageSize"
|
||||
:total="totalElements"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 移动端加载更多 -->
|
||||
<div v-if="isMobile && hasMore && tableData.length > 0" class="mobile-loading">
|
||||
|
||||
Reference in New Issue
Block a user