feat: 新增水印功能

This commit is contained in:
hukdoesn
2025-07-22 10:51:52 +08:00
parent 2c20152694
commit 5c89db4337
7 changed files with 302 additions and 5 deletions

View File

@@ -1,18 +1,138 @@
<template>
<a-config-provider :locale="zhCN" :theme="theme">
<a-watermark
v-if="shouldShowWatermark"
:content="watermarkContent"
>
<a-config-provider :locale="zhCN" :theme="theme">
<router-view></router-view>
</a-config-provider>
</a-watermark>
<a-config-provider
v-else
:locale="zhCN"
:theme="theme"
>
<router-view></router-view>
</a-config-provider>
</template>
<script setup>
import { reactive, computed, onMounted, watch, ref } from 'vue';
import { useRoute } from 'vue-router';
import zhCN from "ant-design-vue/es/locale/zh_CN";
import axios from 'axios';
const route = useRoute();
// 配置 Ant Design Vue 主题,强制使用自定义 PingFang 字体
const theme = {
token: {
fontFamily: "'PingFangCustom', Arial, sans-serif",
},
};
// 水印配置
const watermarkConfig = reactive({
enabled: false,
content: '',
showTime: false,
showUsername: false
});
// 用户信息
const userInfo = reactive({
username: '',
name: ''
});
// 当前日期(年月日)
const currentDate = ref('');
const shouldShowWatermark = computed(() => {
// 排除登陆页面显示水印
if (route.path === '/login') {
return false;
}
return watermarkConfig.enabled;
});
const watermarkContent = computed(() => {
const contents = [];
// 添加自定义水印内容
if (watermarkConfig.content) {
const customContents = watermarkConfig.content.split('\n').filter(line => line.trim());
contents.push(...customContents);
}
// 添加日期水印
if (watermarkConfig.showTime && currentDate.value) {
contents.push(currentDate.value);
}
// 添加用户名水印
if (watermarkConfig.showUsername && userInfo.name) {
contents.push(userInfo.name);
}
return contents.length > 0 ? contents : [];
});
// 更新日期(年月日)
const updateDate = () => {
const now = new Date();
currentDate.value = now.toLocaleDateString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit'
});
};
// 获取水印配置
const fetchWatermarkConfig = async () => {
try {
const response = await axios.get('/api/system/watermark/');
if (response.data.code === 200) {
watermarkConfig.enabled = response.data.data.watermark_enabled;
watermarkConfig.content = response.data.data.watermark_content;
watermarkConfig.showTime = response.data.data.watermark_show_time;
watermarkConfig.showUsername = response.data.data.watermark_show_username;
}
} catch (error) {
console.error('获取水印配置失败:', error);
// 使用默认配置
}
};
// 获取用户信息
const fetchUserInfo = async () => {
try {
const token = localStorage.getItem('token');
if (!token) return;
const response = await axios.get('/api/user/current/', {
headers: { 'Authorization': token }
});
if (response.data.code === 200) {
userInfo.username = response.data.data.username;
userInfo.name = response.data.data.name;
}
} catch (error) {
console.error('获取用户信息失败:', error);
}
};
// 监听路由变化,在非登录页面获取用户信息
watch(() => route.path, (newPath) => {
if (newPath !== '/login') {
fetchUserInfo();
}
}, { immediate: true });
onMounted(() => {
fetchWatermarkConfig();
updateDate();
});
</script>
<style>

View File

@@ -94,6 +94,71 @@
</a-form-item>
</a-form>
<!-- 分割线 -->
<a-divider>水印配置</a-divider>
<!-- 水印功能 -->
<a-form layout="vertical" v-if="hasFunctionPermission('system_basic', 'edit')">
<a-row :gutter="24">
<a-col :span="8">
<a-form-item label="启用水印">
<a-switch
v-model:checked="securityConfig.watermark_enabled"
checked-children="开启"
un-checked-children="关闭"
/>
<div class="form-item-help">
开启后将在页面显示水印
</div>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="显示时间">
<a-switch
v-model:checked="securityConfig.watermark_show_time"
checked-children="显示"
un-checked-children="隐藏"
:disabled="!securityConfig.watermark_enabled"
/>
<div class="form-item-help">
在水印中显示当天日期
</div>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="显示用户名">
<a-switch
v-model:checked="securityConfig.watermark_show_username"
checked-children="显示"
un-checked-children="隐藏"
:disabled="!securityConfig.watermark_enabled"
/>
<div class="form-item-help">
在水印中显示当前用户名
</div>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="24">
<a-col :span="24">
<a-form-item label="自定义水印内容">
<a-textarea
v-model:value="securityConfig.watermark_content"
placeholder="请输入水印内容,支持多行"
:rows="4"
:maxLength="500"
show-count
:disabled="!securityConfig.watermark_enabled"
/>
<div class="form-item-help">
支持多行文本每行一个水印时间和用户名水印会自动添加到自定义内容中
</div>
</a-form-item>
</a-col>
</a-row>
</a-form>
<!-- 分割线 -->
<a-divider>日志清理</a-divider>
@@ -391,7 +456,11 @@ const securityConfig = reactive({
session_timeout: 120,
max_login_attempts: 5,
lockout_duration: 30,
enable_2fa: false
enable_2fa: false,
watermark_enabled: false,
watermark_content: '',
watermark_show_time: false,
watermark_show_username: false
});
const securityRules = {