Selaa lähdekoodia

feat: 修改框架

snihwxf 3 kuukautta sitten
vanhempi
commit
2f8fa5fa48

+ 27 - 0
apps/web-baicai/src/api/system/config.ts

@@ -17,6 +17,30 @@ export namespace ConfigApi {
     id: number;
   }
 
+  export interface AppInfo {
+    [key: string]: any;
+    /**
+     * 登录二次验证
+     */
+    secondaryValidation: boolean;
+    /**
+     * 开启图形验证码
+     */
+    openCaptcha: boolean;
+    /**
+     * 开启水印
+     */
+    openWatermark: boolean;
+    /**
+     * 水印内容
+     */
+    webWatermark: string;
+    /**
+     * 系统主标题
+     */
+    webTitle: string;
+  }
+
   export type PageResult = BasicFetchResult<RecordItem>;
 
   export const getPage = (params: PageParams) =>
@@ -35,4 +59,7 @@ export namespace ConfigApi {
 
   export const deleteDetail = (id: number) =>
     requestClient.delete('/config', { data: { id } });
+
+  export const getWebInfo = () =>
+    requestClient.get<AppInfo>('/config/web-info');
 }

+ 1 - 1
apps/web-baicai/src/components/image-captcha/index.vue

@@ -37,7 +37,7 @@ const props = defineProps({
     default: true,
   },
 });
-const emit = defineEmits(['update:modelValue']);
+const emit = defineEmits(['update:modelValue', 'update:value']);
 
 const modelValue = useVModel(props, 'value', emit, {
   defaultValue: props.value,

+ 3 - 2
apps/web-baicai/src/layouts/basic.vue

@@ -19,7 +19,7 @@ import { useAccessStore, useTabbarStore, useUserStore } from '@vben/stores';
 import { openWindow } from '@vben/utils';
 
 import { $t } from '#/locales';
-import { useAuthStore } from '#/store';
+import { useAppStore, useAuthStore } from '#/store';
 import LoginForm from '#/views/_core/authentication/login.vue';
 
 const { setMenuList } = useTabbarStore();
@@ -70,6 +70,7 @@ const router = useRouter();
 const userStore = useUserStore();
 const authStore = useAuthStore();
 const accessStore = useAccessStore();
+const appStore = useAppStore();
 const { destroyWatermark, updateWatermark } = useWatermark();
 const showDot = computed(() =>
   notifications.value.some((item) => !item.isRead),
@@ -137,7 +138,7 @@ watch(
   async (enable) => {
     if (enable) {
       await updateWatermark({
-        content: `${userStore.userInfo?.username} - ${userStore.userInfo?.realName}`,
+        content: appStore.appInfo?.webWatermark, // `${userStore.userInfo?.username} - ${userStore.userInfo?.realName}`,
       });
     } else {
       destroyWatermark();

+ 45 - 0
apps/web-baicai/src/store/app.ts

@@ -0,0 +1,45 @@
+import { updatePreferences } from '@vben/preferences';
+
+import { acceptHMRUpdate, defineStore } from 'pinia';
+
+import { ConfigApi } from '#/api';
+
+interface AccessState {
+  /**
+   * 配置信息
+   */
+  appInfo: ConfigApi.AppInfo | null;
+}
+
+/**
+ * @zh_CN 配置信息相关
+ */
+export const useAppStore = defineStore('web-info', {
+  actions: {
+    setAppInfo(appInfo: ConfigApi.AppInfo | null) {
+      this.appInfo = appInfo;
+
+      updatePreferences({
+        app: {
+          watermark: appInfo?.openWatermark,
+          name: appInfo?.webTitle,
+        },
+      });
+    },
+
+    async loadAppInfo() {
+      const appInfo = await ConfigApi.getWebInfo();
+      this.setAppInfo(appInfo);
+      return appInfo;
+    },
+  },
+  state: (): AccessState => ({
+    appInfo: null,
+  }),
+});
+
+// 解决热更新问题
+const hot = import.meta.hot;
+if (hot) {
+  hot.accept(acceptHMRUpdate(useAppStore, hot));
+}

+ 1 - 0
apps/web-baicai/src/store/index.ts

@@ -1 +1,2 @@
+export * from './app';
 export * from './auth';

+ 5 - 4
apps/web-baicai/src/views/_core/authentication/login.vue

@@ -7,17 +7,18 @@ import { computed, markRaw, ref, useTemplateRef } from 'vue';
 import { AuthenticationLogin, z } from '@vben/common-ui';
 import { $t } from '@vben/locales';
 
-import { createCaptcha, getCaptchaFlag } from '#/api';
+import { createCaptcha } from '#/api';
 import ImageCaptcha from '#/components/image-captcha/index.vue';
-import { useAuthStore } from '#/store';
+import { useAppStore, useAuthStore } from '#/store';
 
 defineOptions({ name: 'Login' });
 
 const authStore = useAuthStore();
+const appStore = useAppStore();
 const captchaFlag = ref(true);
 
-getCaptchaFlag().then((res: any) => {
-  captchaFlag.value = res;
+appStore.loadAppInfo().then((appInfo: any) => {
+  captchaFlag.value = appInfo.openCaptcha;
 });
 
 const defaultUserName = ['development', 'mock'].includes(import.meta.env.MODE)

+ 27 - 2
apps/web-baicai/src/views/system/config/index.vue

@@ -1,12 +1,17 @@
 <script lang="ts" setup>
 import type { OnActionClickParams, VxeTableGridOptions } from '#/adapter';
 
+import { watch } from 'vue';
+
 import { Page, useVbenModal } from '@vben/common-ui';
+import { useWatermark } from '@vben/hooks';
+import { preferences } from '@vben/preferences';
 
 import { Button, message } from 'ant-design-vue';
 
 import { useTableGridOptions, useVbenVxeGrid } from '#/adapter';
 import { ConfigApi } from '#/api';
+import { useAppStore } from '#/store';
 
 import FormEdit from './components/edit.vue';
 import { useColumns, useSearchSchema } from './data.config';
@@ -16,8 +21,28 @@ const [FormEditModal, formEditApi] = useVbenModal({
   destroyOnClose: true,
 });
 
-const handelSuccess = () => {
-  reload();
+const appStore = useAppStore();
+const { destroyWatermark, updateWatermark } = useWatermark();
+
+watch(
+  () => preferences.app.watermark,
+  async (enable) => {
+    if (enable) {
+      await updateWatermark({
+        content: appStore.appInfo?.webWatermark,
+      });
+    } else {
+      destroyWatermark();
+    }
+  },
+  {
+    immediate: true,
+  },
+);
+
+const handelSuccess = async () => {
+  await reload();
+  await appStore.loadAppInfo();
 };
 const handleDelete = async (id: number) => {
   await ConfigApi.deleteDetail(id);

+ 13 - 1
apps/web-baicai/src/views/system/user/data.config.ts

@@ -4,6 +4,7 @@ import type {
   VxeTableGridOptions,
 } from '#/adapter';
 
+import { z } from '#/adapter';
 import { DepartmentApi, EnumApi, PostApi, UserApi } from '#/api';
 
 export const useSearchSchema = (): VbenFormSchema[] => {
@@ -100,7 +101,13 @@ export const useSchema = (): VbenFormSchema[] => {
       },
       fieldName: 'account',
       label: '账号',
-      rules: 'required',
+      rules: z
+        .string()
+        // .min(3, '账号至少需要3个字符')
+        .regex(
+          /^[a-z]\w{2,}$/i,
+          '账号只能由字母、数字、下划线组成并以字母开头',
+        ),
     },
     {
       component: 'InputPassword',
@@ -155,6 +162,10 @@ export const useSchema = (): VbenFormSchema[] => {
       },
       fieldName: 'phone',
       label: '电话',
+      rules: z
+        .string()
+        .regex(/^1[3-9]\d{9}$/, '电话格式错误')
+        .optional(),
     },
     {
       component: 'Input',
@@ -163,6 +174,7 @@ export const useSchema = (): VbenFormSchema[] => {
       },
       fieldName: 'email',
       label: '邮箱',
+      rules: z.string().email('邮箱格式错误').optional(),
     },
     {
       component: 'Input',