Parcourir la source

feat: 1、新增水印文案自定义功能;2、input-item输入框组件新增清除功能(可用于快捷清除水印文案);3、偏好设置、主题切换、语言选择、是否全屏按钮新增动画效果 (#6800)

* feature: 新增水印文案自定义功能;

* chore: 偏好设置、主题切换、语言选择、是否全屏按钮新增动画效果
zouawen il y a 8 mois
Parent
commit
2ce161e585

+ 8 - 3
apps/web-antd/src/layouts/basic.vue

@@ -106,11 +106,16 @@ function handleMakeAll() {
   notifications.value.forEach((item) => (item.isRead = true));
 }
 watch(
-  () => preferences.app.watermark,
-  async (enable) => {
+  () => ({
+    enable: preferences.app.watermark,
+    content: preferences.app.watermarkContent,
+  }),
+  async ({ enable, content }) => {
     if (enable) {
       await updateWatermark({
-        content: `${userStore.userInfo?.username} - ${userStore.userInfo?.realName}`,
+        content:
+          content ||
+          `${userStore.userInfo?.username} - ${userStore.userInfo?.realName}`,
       });
     } else {
       destroyWatermark();

+ 8 - 3
apps/web-ele/src/layouts/basic.vue

@@ -106,11 +106,16 @@ function handleMakeAll() {
   notifications.value.forEach((item) => (item.isRead = true));
 }
 watch(
-  () => preferences.app.watermark,
-  async (enable) => {
+  () => ({
+    enable: preferences.app.watermark,
+    content: preferences.app.watermarkContent,
+  }),
+  async ({ enable, content }) => {
     if (enable) {
       await updateWatermark({
-        content: `${userStore.userInfo?.username} - ${userStore.userInfo?.realName}`,
+        content:
+          content ||
+          `${userStore.userInfo?.username} - ${userStore.userInfo?.realName}`,
       });
     } else {
       destroyWatermark();

+ 8 - 3
apps/web-naive/src/layouts/basic.vue

@@ -107,11 +107,16 @@ function handleMakeAll() {
 }
 
 watch(
-  () => preferences.app.watermark,
-  async (enable) => {
+  () => ({
+    enable: preferences.app.watermark,
+    content: preferences.app.watermarkContent,
+  }),
+  async ({ enable, content }) => {
     if (enable) {
       await updateWatermark({
-        content: `${userStore.userInfo?.username} - ${userStore.userInfo?.realName}`,
+        content:
+          content ||
+          `${userStore.userInfo?.username} - ${userStore.userInfo?.realName}`,
       });
     } else {
       destroyWatermark();

+ 14 - 0
packages/@core/base/design/src/css/ui.css

@@ -85,3 +85,17 @@
 .z-popup {
   z-index: var(--popup-z-index);
 }
+
+@keyframes shrink {
+  0% {
+    transform: scale(1);
+  }
+
+  50% {
+    transform: scale(0.9);
+  }
+
+  100% {
+    transform: scale(1);
+  }
+}

+ 1 - 0
packages/@core/preferences/src/config.ts

@@ -29,6 +29,7 @@ const defaultPreferences: Preferences = {
     name: 'Vben Admin',
     preferencesButtonPosition: 'auto',
     watermark: false,
+    watermarkContent: '',
     zIndex: 200,
   },
   breadcrumb: {

+ 4 - 0
packages/@core/preferences/src/types.ts

@@ -75,6 +75,10 @@ interface AppPreferences {
    * @zh_CN 是否开启水印
    */
   watermark: boolean;
+  /**
+   * @zh_CN 水印文案
+   */
+  watermarkContent: string;
   /** z-index */
   zIndex: number;
 }

+ 4 - 1
packages/@core/ui-kit/shadcn-ui/src/components/full-screen/full-screen.vue

@@ -21,7 +21,10 @@ isFullscreen.value = !!(
 );
 </script>
 <template>
-  <VbenIconButton @click="toggle">
+  <VbenIconButton
+    class="hover:animate-[shrink_0.3s_ease-in-out]"
+    @click="toggle"
+  >
     <Minimize v-if="isFullscreen" class="text-foreground size-4" />
     <Maximize v-else class="text-foreground size-4" />
   </VbenIconButton>

+ 1 - 1
packages/effects/layouts/src/widgets/language-toggle.vue

@@ -31,7 +31,7 @@ async function handleUpdate(value: string | undefined) {
       :model-value="preferences.app.locale"
       @update:model-value="handleUpdate"
     >
-      <VbenIconButton>
+      <VbenIconButton class="hover:animate-[shrink_0.3s_ease-in-out]">
         <Languages class="text-foreground size-4" />
       </VbenIconButton>
     </VbenDropdownRadioMenu>

+ 17 - 1
packages/effects/layouts/src/widgets/preferences/blocks/general/general.vue

@@ -2,6 +2,7 @@
 import { SUPPORT_LANGUAGES } from '@vben/constants';
 import { $t } from '@vben/locales';
 
+import InputItem from '../input-item.vue';
 import SelectItem from '../select-item.vue';
 import SwitchItem from '../switch-item.vue';
 
@@ -12,6 +13,7 @@ defineOptions({
 const appLocale = defineModel<string>('appLocale');
 const appDynamicTitle = defineModel<boolean>('appDynamicTitle');
 const appWatermark = defineModel<boolean>('appWatermark');
+const appWatermarkContent = defineModel<string>('appWatermarkContent');
 const appEnableCheckUpdates = defineModel<boolean>('appEnableCheckUpdates');
 </script>
 
@@ -22,9 +24,23 @@ const appEnableCheckUpdates = defineModel<boolean>('appEnableCheckUpdates');
   <SwitchItem v-model="appDynamicTitle">
     {{ $t('preferences.dynamicTitle') }}
   </SwitchItem>
-  <SwitchItem v-model="appWatermark">
+  <SwitchItem
+    v-model="appWatermark"
+    @update:model-value="
+      (val) => {
+        if (!val) appWatermarkContent = '';
+      }
+    "
+  >
     {{ $t('preferences.watermark') }}
   </SwitchItem>
+  <InputItem
+    v-if="appWatermark"
+    v-model="appWatermarkContent"
+    :placeholder="$t('preferences.watermarkContent')"
+  >
+    {{ $t('preferences.watermarkContent') }}
+  </InputItem>
   <SwitchItem v-model="appEnableCheckUpdates">
     {{ $t('preferences.checkUpdates') }}
   </SwitchItem>

+ 13 - 2
packages/effects/layouts/src/widgets/preferences/blocks/input-item.vue

@@ -3,7 +3,7 @@ import type { SelectOption } from '@vben/types';
 
 import { useSlots } from 'vue';
 
-import { CircleHelp } from '@vben/icons';
+import { CircleHelp, CircleX } from '@vben/icons';
 
 import { Input, VbenTooltip } from '@vben-core/shadcn-ui';
 
@@ -47,6 +47,17 @@ const slots = useSlots();
         <slot name="tip"></slot>
       </VbenTooltip>
     </span>
-    <Input v-model="inputValue" class="h-8 w-[165px]" />
+    <div class="relative">
+      <Input
+        v-model="inputValue"
+        class="h-8 w-[165px]"
+        :placeholder="placeholder"
+      />
+      <CircleX
+        v-if="inputValue"
+        class="hover:text-foreground text-foreground/60 absolute right-2 top-1/2 size-3 -translate-y-1/2 transform cursor-pointer"
+        @click="() => (inputValue = '')"
+      />
+    </div>
   </div>
 </template>

+ 1 - 1
packages/effects/layouts/src/widgets/preferences/preferences-button.vue

@@ -13,7 +13,7 @@ function clearPreferencesAndLogout() {
 </script>
 <template>
   <Preferences @clear-preferences-and-logout="clearPreferencesAndLogout">
-    <VbenIconButton>
+    <VbenIconButton class="hover:animate-[shrink_0.3s_ease-in-out]">
       <Settings class="text-foreground size-4" />
     </VbenIconButton>
   </Preferences>

+ 2 - 0
packages/effects/layouts/src/widgets/preferences/preferences-drawer.vue

@@ -67,6 +67,7 @@ const appColorGrayMode = defineModel<boolean>('appColorGrayMode');
 const appColorWeakMode = defineModel<boolean>('appColorWeakMode');
 const appContentCompact = defineModel<ContentCompactType>('appContentCompact');
 const appWatermark = defineModel<boolean>('appWatermark');
+const appWatermarkContent = defineModel<string>('appWatermarkContent');
 const appEnableCheckUpdates = defineModel<boolean>('appEnableCheckUpdates');
 const appPreferencesButtonPosition = defineModel<PreferencesButtonPositionType>(
   'appPreferencesButtonPosition',
@@ -267,6 +268,7 @@ async function handleReset() {
                 v-model:app-enable-check-updates="appEnableCheckUpdates"
                 v-model:app-locale="appLocale"
                 v-model:app-watermark="appWatermark"
+                v-model:app-watermark-content="appWatermarkContent"
               />
             </Block>
 

+ 1 - 1
packages/effects/layouts/src/widgets/theme-toggle/theme-button.vue

@@ -88,7 +88,7 @@ function toggleTheme(event: MouseEvent) {
     :aria-label="theme"
     :class="[`is-${theme}`]"
     aria-live="polite"
-    class="theme-toggle cursor-pointer border-none bg-none"
+    class="theme-toggle cursor-pointer border-none bg-none hover:animate-[shrink_0.3s_ease-in-out]"
     v-bind="bindProps"
     @click.stop="toggleTheme"
   >

+ 1 - 0
packages/locales/src/langs/en-US/preferences.json

@@ -37,6 +37,7 @@
   "language": "Language",
   "dynamicTitle": "Dynamic Title",
   "watermark": "Watermark",
+  "watermarkContent": "Please input Watermark content",
   "checkUpdates": "Periodic update check",
   "position": {
     "title": "Preferences Postion",

+ 1 - 0
packages/locales/src/langs/zh-CN/preferences.json

@@ -37,6 +37,7 @@
   "language": "语言",
   "dynamicTitle": "动态标题",
   "watermark": "水印",
+  "watermarkContent": "请输入水印文案",
   "checkUpdates": "定时检查更新",
   "position": {
     "title": "偏好设置位置",

+ 8 - 3
playground/src/layouts/basic.vue

@@ -122,11 +122,16 @@ function handleMakeAll() {
 function handleClickLogo() {}
 
 watch(
-  () => preferences.app.watermark,
-  async (enable) => {
+  () => ({
+    enable: preferences.app.watermark,
+    content: preferences.app.watermarkContent,
+  }),
+  async ({ enable, content }) => {
     if (enable) {
       await updateWatermark({
-        content: `${userStore.userInfo?.username} - ${userStore.userInfo?.realName}`,
+        content:
+          content ||
+          `${userStore.userInfo?.username} - ${userStore.userInfo?.realName}`,
       });
     } else {
       destroyWatermark();