refactor: 系统水印重构

This commit is contained in:
meilin.huang
2023-10-14 00:38:51 +08:00
parent e0f1f40ba0
commit 77ae6e3bab
20 changed files with 139 additions and 123 deletions

View File

@@ -15,7 +15,7 @@
"countup.js": "^2.7.0",
"cropperjs": "^1.5.11",
"echarts": "^5.4.0",
"element-plus": "^2.3.14",
"element-plus": "^2.4.0",
"jsencrypt": "^3.3.1",
"lodash": "^4.17.21",
"mitt": "^3.0.1",
@@ -23,14 +23,14 @@
"monaco-sql-languages": "^0.11.0",
"monaco-themes": "^0.4.4",
"nprogress": "^0.2.0",
"pinia": "^2.1.6",
"pinia": "^2.1.7",
"qrcode.vue": "^3.4.0",
"screenfull": "^6.0.2",
"sortablejs": "^1.15.0",
"sql-formatter": "^12.1.2",
"vue": "^3.3.4",
"vue-clipboard3": "^1.0.1",
"vue-router": "^4.2.4",
"vue-router": "^4.2.5",
"xterm": "^5.3.0",
"xterm-addon-fit": "^0.8.0",
"xterm-addon-search": "^0.13.0",

View File

@@ -1,21 +1,32 @@
<template>
<router-view v-show="themeConfig.lockScreenTime !== 0" />
<el-watermark
:zIndex="10000000"
:width="200"
v-if="themeConfig.isWartermark"
:font="{ color: 'rgba(180, 180, 180, 0.5)' }"
:content="state.watermarkContent"
>
<router-view v-show="themeConfig.lockScreenTime !== 0" />
</el-watermark>
<router-view v-if="!themeConfig.isWartermark" v-show="themeConfig.lockScreenTime !== 0" />
<LockScreen v-if="themeConfig.isLockScreen" />
<Setings ref="setingsRef" v-show="themeConfig.lockScreenTime !== 0" />
</template>
<script setup lang="ts" name="app">
import { ref, onBeforeMount, onMounted, onUnmounted, nextTick, watch } from 'vue';
import { ref, reactive, onBeforeMount, onMounted, onUnmounted, nextTick, watch } from 'vue';
import { useRoute } from 'vue-router';
// import { useTagsViewRoutes } from '@/store/tagsViewRoutes';
import { storeToRefs } from 'pinia';
import { useThemeConfig } from '@/store/themeConfig';
import { getLocal } from '@/common/utils/storage';
import LockScreen from '@/layout/lockScreen/index.vue';
import Setings from '@/layout/navBars/breadcrumb/setings.vue';
import Watermark from '@/common/utils/wartermark';
import mittBus from '@/common/utils/mitt';
import { getThemeConfig } from './common/utils/storage';
import { dateFormat2 } from '@/common/utils/date';
import { useWartermark } from '@/common/sysconfig';
import { useUserInfo } from '@/store/userInfo';
const setingsRef = ref();
const route = useRoute();
@@ -23,6 +34,11 @@ const route = useRoute();
const themeConfigStores = useThemeConfig();
const { themeConfig } = storeToRefs(themeConfigStores);
const state = reactive({
useWatermark: false,
watermarkContent: [] as any,
});
// 布局配置弹窗打开
const openSetingsDrawer = () => {
setingsRef.value.openDrawer();
@@ -39,6 +55,11 @@ onBeforeMount(() => {
// 页面加载时
onMounted(() => {
nextTick(() => {
// 是否开启水印
useWartermark().then((res) => {
themeConfigStores.setWatermarkConfig(res);
});
// 监听布局配置弹窗点击打开
mittBus.on('openSetingsDrawer', () => {
openSetingsDrawer();
@@ -55,8 +76,52 @@ onMounted(() => {
});
});
// 监听 themeConfig isWartermark配置文件的变化
watch(
() => themeConfig.value.isWartermark,
(val) => {
if (val) {
setTimeout(() => {
setWatermarkContent();
refreshWatermarkTime();
}, 1500);
}
}
);
const setWatermarkContent = () => {
const userinfo = useUserInfo().userInfo;
if (!userinfo) {
themeConfig.value.isWartermark = false;
return;
}
state.watermarkContent = [`${userinfo.username}(${userinfo.name})`, dateFormat2('yyyy-MM-dd HH:mm:ss', new Date())];
// 存在额外水印信息,则追加水印信息
if (themeConfig.value.wartermarkText?.trim()) {
state.watermarkContent.push(themeConfig.value.wartermarkText);
}
};
let refreshWatermarkTimeInterval: any = null;
/**
* 刷新水印时间
*/
const refreshWatermarkTime = () => {
if (refreshWatermarkTimeInterval) {
clearInterval(refreshWatermarkTimeInterval);
}
refreshWatermarkTimeInterval = setInterval(() => {
if (themeConfig.value.isWartermark) {
state.watermarkContent[1] = dateFormat2('yyyy-MM-dd HH:mm:ss', new Date());
} else {
clearInterval(refreshWatermarkTimeInterval);
}
}, 10000);
};
// 页面销毁时,关闭监听布局配置
onUnmounted(() => {
clearInterval(refreshWatermarkTimeInterval);
mittBus.off('openSetingsDrawer', () => {});
});
@@ -65,8 +130,6 @@ watch(
() => route.path,
() => {
nextTick(() => {
// 路由变化更新水印
Watermark.use();
document.title = `${route.meta.title} - ${themeConfig.value.globalTitle}` || themeConfig.value.globalTitle;
});
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -11,7 +11,7 @@ const config = {
baseWsUrl: `${(window as any).globalConfig.BaseWsUrl || `${location.protocol == 'https:' ? 'wss:' : 'ws:'}//${getBaseApiUrl()}`}/api`,
// 系统版本
version: 'v1.5.2',
version: 'v1.5.3',
};
export default config;

View File

@@ -53,12 +53,21 @@ export async function useLoginCaptcha(): Promise<boolean> {
}
/**
* 是否启用水印
* 是否启用水印信息配置
*
* @returns
*/
export async function useWartermark(): Promise<boolean> {
return await getBoolConfigValue(UseWartermarkConfigKey, true);
export async function useWartermark(): Promise<any> {
const value = await getConfigValue(UseWartermarkConfigKey);
if (!value) {
return {
isUse: true,
};
}
const jsonValue = JSON.parse(value);
// 将字符串转为bool
jsonValue.isUse = convertBool(jsonValue.isUse, true);
return jsonValue;
}
function convertBool(value: string, defaultValue: boolean) {
@@ -77,4 +86,3 @@ export async function getLdapEnabled(): Promise<any> {
const value = await openApi.getLdapEnabled();
return convertBool(value, false);
}

View File

@@ -30,15 +30,6 @@ export function getThemeConfig() {
return getLocal('themeConfig');
}
// 获取是否开启水印
export function getUseWatermark() {
return getLocal('useWatermark');
}
export function saveUseWatermark(useWatermark: boolean) {
setLocal('useWatermark', useWatermark);
}
// 清除用户相关的用户信息
export function clearUser() {
removeLocal(TokenKey);

View File

@@ -1,68 +0,0 @@
import { getUseWatermark, getUser } from '@/common/utils/storage';
import { dateFormat2 } from '@/common/utils/date';
// 页面添加水印效果
const setWatermark = (str: any) => {
const id = '1.23452384164.123412416';
if (document.getElementById(id) !== null) document.body.removeChild(document.getElementById(id) as any);
const can = document.createElement('canvas');
can.width = 400;
can.height = 250;
const cans: any = can.getContext('2d');
cans.rotate((-20 * Math.PI) / 180);
cans.font = '14px Vedana';
cans.fillStyle = 'rgba(200, 200, 200, 0.35)';
cans.textAlign = 'left';
cans.textBaseline = 'Middle';
// cans.fillText('mayfly go', can.width / 4, can.height )
cans.fillText(str, can.width / 8, can.height / 2);
const div = document.createElement('div');
div.id = id;
div.style.pointerEvents = 'none';
div.style.top = '30px';
div.style.left = '0px';
div.style.position = 'fixed';
div.style.zIndex = '10000000';
div.style.width = document.documentElement.clientWidth + 'px';
div.style.height = document.documentElement.clientHeight + 'px';
div.style.background = `url(${can.toDataURL('image/png')}) left top repeat`;
document.body.appendChild(div);
return id;
};
function set(str: any) {
let id = setWatermark(str);
if (document.getElementById(id) === null) id = setWatermark(str);
}
function del() {
let id = '1.23452384164.123412416';
if (document.getElementById(id) !== null) document.body.removeChild(document.getElementById(id) as any);
}
const watermark = {
use: () => {
const userinfo = getUser();
if (!userinfo) {
del();
}
setTimeout(() => {
if (getUseWatermark()) {
set(`${userinfo.username} ${dateFormat2('yyyy-MM-dd HH:mm:ss', new Date())}`);
} else {
del();
}
}, 1500);
},
// 设置水印
set: (str: any) => {
set(str);
},
// 删除水印
del: () => {
del();
},
};
export default watermark;

View File

@@ -89,8 +89,8 @@ export const useThemeConfig = defineStore('themeConfig', {
isInvert: false,
// 是否开启水印
isWartermark: false,
// 水印文案
wartermarkText: 'mayfly',
// 额外水印文案
wartermarkText: '',
/* 其它设置
------------------------------- */
@@ -152,5 +152,10 @@ export const useThemeConfig = defineStore('themeConfig', {
this.themeConfig.editorTheme = 'SolarizedLight';
}
},
// 设置水印配置信息
setWatermarkConfig(useWatermarkConfig: any) {
this.themeConfig.isWartermark = useWatermarkConfig.isUse;
this.themeConfig.wartermarkText = useWatermarkConfig.content;
},
},
});

View File

@@ -12,7 +12,7 @@
</div>
</div>
<div class="right">
<img src="@/assets/image/401.png" />
<img src="@/assets/image/401.svg" />
</div>
</div>
</div>
@@ -20,7 +20,7 @@
<script lang="ts">
import { useRouter } from 'vue-router';
import { clearSession } from '@/common/utils/storage.ts';
import { clearSession } from '@/common/utils/storage';
export default {
name: '401',
setup() {
@@ -39,7 +39,7 @@ export default {
<style scoped lang="scss">
.error {
height: 100%;
background-color: white;
background-color: var(--bg-main-color);
display: flex;
.error-flex {
margin: auto;

View File

@@ -12,7 +12,7 @@
</div>
</div>
<div class="right">
<img src="@/assets/image/404.png" />
<img src="@/assets/image/404.svg" />
</div>
</div>
</div>
@@ -37,7 +37,7 @@ export default {
<style scoped lang="scss">
.error {
height: 100%;
background-color: white;
background-color: var(--bg-main-color);
display: flex;
.error-flex {
margin: auto;

View File

@@ -132,7 +132,7 @@ import { nextTick, onMounted, ref, toRefs, reactive, computed } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { ElMessage } from 'element-plus';
import { initRouter } from '@/router/index';
import { saveToken, saveUser, saveUseWatermark } from '@/common/utils/storage';
import { saveToken, saveUser } from '@/common/utils/storage';
import { formatAxis } from '@/common/utils/format';
import openApi from '@/common/openApi';
import { RsaEncrypt } from '@/common/rsa';
@@ -142,7 +142,8 @@ import { useUserInfo } from '@/store/userInfo';
import QrcodeVue from 'qrcode.vue';
import { personApi } from '@/views/personal/api';
import { AccountUsernamePattern } from '@/common/pattern';
import { getToken } from '../../../common/utils/storage';
import { getToken } from '@/common/utils/storage';
import { useThemeConfig } from '@/store/themeConfig';
const rules = {
username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
@@ -150,6 +151,9 @@ const rules = {
captcha: [{ required: true, message: '请输入验证码', trigger: 'blur' }],
};
// 定义变量内容
const storesThemeConfig = useThemeConfig();
const route = useRoute();
const router = useRouter();
const loginFormRef: any = ref(null);
@@ -405,7 +409,8 @@ const toIndex = async () => {
// 关闭 loading
state.loading.signIn = true;
ElMessage.success(`${currentTimeInfo},欢迎回来!`);
saveUseWatermark(await useWartermark());
// 水印信息配置
storesThemeConfig.setWatermarkConfig(await useWartermark());
}, 300);
};

View File

@@ -78,6 +78,7 @@ const getThemeConfig = computed(() => {
});
onMounted(async () => {
getThemeConfig.value.isWartermark = false;
state.oauth2LoginConfig = await openApi.oauth2LoginConfig();
});

View File

@@ -195,15 +195,6 @@
操作
</template>
<template #default="scope">
<el-link
@click="downloadFile(scope.row)"
v-if="scope.row.type == '-'"
v-auth="'machine:file:write'"
type="primary"
icon="download"
:underline="false"
></el-link>
<el-link
@click="deleteFile([scope.row])"
v-if="!dontOperate(scope.row)"
@@ -211,7 +202,18 @@
type="danger"
icon="delete"
:underline="false"
title="删除"
></el-link>
<el-link
@click="downloadFile(scope.row)"
v-if="scope.row.type == '-'"
v-auth="'machine:file:write'"
type="primary"
icon="download"
:underline="false"
class="ml10"
title="下载"
></el-link>
<el-popover placement="top-start" :title="`${scope.row.path}-文件详情`" :width="520" trigger="click" @show="showFileStat(scope.row)">

View File

@@ -773,10 +773,10 @@ echarts@^5.4.0:
tslib "2.3.0"
zrender "5.4.0"
element-plus@^2.3.14:
version "2.3.14"
resolved "https://registry.npmmirror.com/element-plus/-/element-plus-2.3.14.tgz#302a23916b0c3375fcf4b927d7b94483dac13e1b"
integrity sha512-9yvxUaU4jXf2ZNPdmIxoj/f8BG8CDcGM6oHa9JIqxLjQlfY4bpzR1E5CjNimnOX3rxO93w1TQ0jTVt0RSxh9kA==
element-plus@^2.4.0:
version "2.4.0"
resolved "https://registry.npmmirror.com/element-plus/-/element-plus-2.4.0.tgz#e79249ac4c0a606d377c2f31ad553aa992286fe3"
integrity sha512-yJEa8LXkGOOgkfkeqMMEdeX/Dc8EH9qPcRuX91dlhSXxgCKKbp9tH3QFTOG99ibZsrN/Em62nh7ddvbc7I1frw==
dependencies:
"@ctrl/tinycolor" "^3.4.1"
"@element-plus/icons-vue" "^2.0.6"
@@ -1502,10 +1502,10 @@ picomatch@^2.2.3:
resolved "https://registry.nlark.com/picomatch/download/picomatch-2.3.0.tgz?cache=0&sync_timestamp=1621648246651&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fpicomatch%2Fdownload%2Fpicomatch-2.3.0.tgz"
integrity sha1-8fBh3o9qS/AiiS4tEoI0+5gwKXI=
pinia@^2.1.6:
version "2.1.6"
resolved "https://registry.npmmirror.com/pinia/-/pinia-2.1.6.tgz#e88959f14b61c4debd9c42d0c9944e2875cbe0fa"
integrity sha512-bIU6QuE5qZviMmct5XwCesXelb5VavdOWKWaB17ggk++NUwQWWbP5YnsONTk3b752QkW9sACiR81rorpeOMSvQ==
pinia@^2.1.7:
version "2.1.7"
resolved "https://registry.npmmirror.com/pinia/-/pinia-2.1.7.tgz#4cf5420d9324ca00b7b4984d3fbf693222115bbc"
integrity sha512-+C2AHFtcFqjPih0zpYuvof37SFxMQ7OEG2zV9jRI12i9BOy3YQVAHwdKtyyc8pDcDyIc33WCIsZaCFWU7WWxGQ==
dependencies:
"@vue/devtools-api" "^6.5.0"
vue-demi ">=0.14.5"
@@ -1835,10 +1835,10 @@ vue-eslint-parser@^9.3.1:
lodash "^4.17.21"
semver "^7.3.6"
vue-router@^4.2.4:
version "4.2.4"
resolved "https://registry.npmmirror.com/vue-router/-/vue-router-4.2.4.tgz#382467a7e2923e6a85f015d081e1508052c191b9"
integrity sha512-9PISkmaCO02OzPVOMq2w82ilty6+xJmQrarYZDkjZBfl4RvYAlt4PKnEX21oW4KTtWfa9OuO/b3qk1Od3AEdCQ==
vue-router@^4.2.5:
version "4.2.5"
resolved "https://registry.npmmirror.com/vue-router/-/vue-router-4.2.5.tgz#b9e3e08f1bd9ea363fdd173032620bc50cf0e98a"
integrity sha512-DIUpKcyg4+PTQKfFPX88UWhlagBEBEfJ5A8XDXRJLUnZOvcpMF8o/dnL90vpVkGaPbjvXazV/rC1qBKrZlFugw==
dependencies:
"@vue/devtools-api" "^6.5.0"

View File

@@ -4,7 +4,7 @@ import "fmt"
const (
AppName = "mayfly-go"
Version = "v1.5.2"
Version = "v1.5.3"
)
func GetAppInfo() string {

View File

@@ -0,0 +1,7 @@
UPDATE `t_sys_config`
SET
`params` = '[{"name":"是否启用","model":"isUse","placeholder":"是否启用水印","options":"true,false"},{"name":"自定义信息","model":"content","placeholder":"额外添加的水印内容,可添加公司名称等"}]',
`value` = '',
`remark` = '水印信息配置'
WHERE
`key` = 'UseWartermark';