样式修正,支持配置登录方式、icon等

This commit is contained in:
2025-12-24 14:12:44 +08:00
parent 3d1e19030a
commit 3499a516fe
33 changed files with 246 additions and 345 deletions

View File

@@ -24,10 +24,10 @@ INSERT INTO `tb_sys_config` (`id`, `config_key`, `config_name`, `config_value`,
-- 基础配置Logo、系统信息
('100', 'system.name', '系统名称', '红色思政学习平台', 'string', 'input', '基础配置', '系统显示名称', '请输入系统名称', '系统对外显示的名称', NULL, NULL, NULL, NULL, NULL, 100, 1, '1', now()),
('101', 'system.shortName', '系统简称', '思政平台', 'string', 'input', '基础配置', '系统简称', '请输入系统简称', '系统的简短名称', NULL, NULL, NULL, NULL, NULL, 101, 1, '1', now()),
('102', 'system.logo.login', '登录页Logo', '', 'string', 'imgupload', '基础配置', '登录页Logo', NULL, '存储文件ID建议尺寸120x120px', NULL, NULL, NULL, NULL, NULL, 102, 1, '1', now()),
('103', 'system.logo.home', '首页Logo', '', 'string', 'imgupload', '基础配置', '首页Logo', NULL, '存储文件ID建议尺寸120x40px', NULL, NULL, NULL, NULL, NULL, 103, 1, '1', now()),
('104', 'system.logo.admin', '管理后台Logo', '', 'string', 'imgupload', '基础配置', '管理后台Logo', NULL, '存储文件ID建议尺寸40x40px', NULL, NULL, NULL, NULL, NULL, 104, 1, '1', now()),
('105', 'system.favicon', '网站图标', '', 'string', 'imgupload', '基础配置', '网站图标', NULL, '存储文件ID建议格式ico/png尺寸32x32px', NULL, NULL, NULL, NULL, NULL, 105, 1, '1', now()),
('102', 'system.logo.login', '登录页Logo', '', 'string', 'imgupload', '基础配置', '登录页Logo', NULL, '存储文件ID建议尺寸36x36px', NULL, NULL, NULL, NULL, NULL, 102, 1, '1', now()),
('103', 'system.logo.home', '首页Logo', '', 'string', 'imgupload', '基础配置', '首页Logo', NULL, '存储文件ID建议尺寸36x36px', NULL, NULL, NULL, NULL, NULL, 103, 1, '1', now()),
('104', 'system.logo.admin', '管理后台Logo', '', 'string', 'imgupload', '基础配置', '管理后台Logo', NULL, '存储文件ID建议尺寸36x36px', NULL, NULL, NULL, NULL, NULL, 104, 1, '1', now()),
('105', 'system.favicon', '网站图标', '', 'string', 'imgupload', '基础配置', '网站图标', NULL, '存储文件ID建议格式ico/png尺寸36x36px', NULL, NULL, NULL, NULL, NULL, 105, 1, '1', now()),
-- 邮件配置
('40', 'email.login.enabled', '启用邮箱登录', 'false', 'boolean', 'switch', '邮件配置', '是否启用邮箱登录', NULL, '关闭后登录页将不显示邮箱登录选项', NULL, NULL, NULL, NULL, NULL, 40, 1, '1', now()),

View File

@@ -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;
}
}

View File

@@ -31,4 +31,10 @@ function changeHome(){
</script>
<style scoped lang="scss">
.change-home{
.change-home-item{
cursor: pointer;
color: #333;
}
}
</style>

View File

@@ -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 }>>({});

View File

@@ -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']);

View File

@@ -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、系统名称、登录开关等

View File

@@ -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';
}
},

View File

@@ -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;
}
}
}

View File

@@ -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: 知识库详情覆盖在列表上方 -->

View File

@@ -1231,13 +1231,6 @@ onMounted(() => {
}
}
// 分页组件
// .pagination-container {
// margin-top: 24px;
// display: flex;
// justify-content: center;
// padding: 20px 0;
// }
// ==================== 下拉选择器样式 ====================
.select-container {

View File

@@ -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 {

View File

@@ -753,12 +753,6 @@ onMounted(() => {
}
}
.pagination-container {
margin-top: 20px;
display: flex;
justify-content: flex-end;
}
.cron-examples {
div {
padding: 6px 0;

View File

@@ -526,11 +526,6 @@ function handleSizeChange(size: number) {
// el-table和el-button会自动处理样式和交互
.pagination-container {
display: flex;
justify-content: center;
margin-top: 20px;
}

View File

@@ -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>
<!-- 创建/编辑对话框 -->

View File

@@ -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

View File

@@ -768,14 +768,6 @@ onMounted(() => {
}
}
}
// 分页容器
.pagination-container {
margin-top: 20px;
display: flex;
justify-content: flex-end;
}
// 详情对话框样式
.detail-content {
max-height: 70vh;

View File

@@ -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;
}
/**

View File

@@ -603,11 +603,6 @@ function handleSizeChange(size: number) {
}
}
.pagination-container {
display: flex;
justify-content: flex-end;
margin-top: 24px;
}
.tag-container {
display: flex;

View File

@@ -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;

View File

@@ -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>

View File

@@ -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;
}
}

View File

@@ -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;

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -886,6 +886,10 @@ function getItemStatusType(status?: number): 'info' | 'warning' | 'success' {
.resource-action {
flex-shrink: 0;
button {
background-color: #C62828;
border: none;
}
}
}

View File

@@ -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>

View File

@@ -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;
}
}
}
}
}

View File

@@ -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;

View File

@@ -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>

View File

@@ -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>

View File

@@ -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">