diff --git a/build/plugins/index.ts b/build/plugins/index.ts index debec678..1441cc2f 100644 --- a/build/plugins/index.ts +++ b/build/plugins/index.ts @@ -7,6 +7,7 @@ import { setupElegantRouter } from './router'; import { setupUnocss } from './unocss'; import { setupUnplugin } from './unplugin'; import { setupHtmlPlugin } from './html'; +import { setupMonacoEditorPlugin } from './monaco-editor'; export function setupVitePlugins(viteEnv: Env.ImportMeta, buildTime: string) { const plugins: PluginOption = [ @@ -21,7 +22,8 @@ export function setupVitePlugins(viteEnv: Env.ImportMeta, buildTime: string) { setupUnocss(viteEnv), ...setupUnplugin(viteEnv), progress(), - setupHtmlPlugin(buildTime) + setupHtmlPlugin(buildTime), + setupMonacoEditorPlugin() ]; return plugins; diff --git a/build/plugins/monaco-editor.ts b/build/plugins/monaco-editor.ts new file mode 100644 index 00000000..c17dd8e7 --- /dev/null +++ b/build/plugins/monaco-editor.ts @@ -0,0 +1,7 @@ +import monacoEditorPlugin from 'vite-plugin-monaco-editor'; + +export function setupMonacoEditorPlugin() { + return (monacoEditorPlugin as any).default({ + languageWorkers: ['editorWorkerService', 'css', 'html', 'json', 'typescript'] + }); +} diff --git a/package.json b/package.json index 2a6bcd1c..6f9df20d 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "dayjs": "1.11.12", "echarts": "5.5.1", "jsencrypt": "^3.3.2", + "monaco-editor": "^0.48.0", "naive-ui": "2.39.0", "nprogress": "0.2.0", "pinia": "2.2.2", @@ -82,6 +83,7 @@ "unplugin-icons": "0.19.2", "unplugin-vue-components": "0.27.4", "vite": "5.4.1", + "vite-plugin-monaco-editor": "^1.1.0", "vite-plugin-progress": "0.0.7", "vite-plugin-svg-icons": "2.0.1", "vite-plugin-vue-devtools": "7.3.8", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4292e953..94296913 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -44,6 +44,9 @@ importers: jsencrypt: specifier: ^3.3.2 version: 3.3.2 + monaco-editor: + specifier: ^0.48.0 + version: 0.48.0 naive-ui: specifier: 2.39.0 version: 2.39.0(vue@3.4.38(typescript@5.5.4)) @@ -147,6 +150,9 @@ importers: vite: specifier: 5.4.1 version: 5.4.1(@types/node@22.4.1)(sass@1.77.8) + vite-plugin-monaco-editor: + specifier: ^1.1.0 + version: 1.1.0(monaco-editor@0.48.0) vite-plugin-progress: specifier: 0.0.7 version: 0.0.7(vite@5.4.1(@types/node@22.4.1)(sass@1.77.8)) @@ -3042,6 +3048,9 @@ packages: mlly@1.7.1: resolution: {integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==} + monaco-editor@0.48.0: + resolution: {integrity: sha512-goSDElNqFfw7iDHMg8WDATkfcyeLTNpBHQpO8incK6p5qZt5G/1j41X0xdGzpIkGojGXM+QiRQyLjnfDVvrpwA==} + mrmime@2.0.0: resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==} engines: {node: '>=10'} @@ -4025,6 +4034,11 @@ packages: '@nuxt/kit': optional: true + vite-plugin-monaco-editor@1.1.0: + resolution: {integrity: sha512-IvtUqZotrRoVqwT0PBBDIZPNraya3BxN/bfcNfnxZ5rkJiGcNtO5eAOWWSgT7zullIAEqQwxMU83yL9J5k7gww==} + peerDependencies: + monaco-editor: '>=0.33.0' + vite-plugin-progress@0.0.7: resolution: {integrity: sha512-zyvKdcc/X+6hnw3J1HVV1TKrlFKC4Rh8GnDnWG/2qhRXjqytTcM++xZ+SAPnoDsSyWl8O93ymK0wZRgHAoglEQ==} engines: {node: '>=14', pnpm: '>=7.0.0'} @@ -7270,6 +7284,8 @@ snapshots: pkg-types: 1.1.3 ufo: 1.5.4 + monaco-editor@0.48.0: {} + mrmime@2.0.0: {} ms@2.0.0: {} @@ -8335,6 +8351,10 @@ snapshots: - rollup - supports-color + vite-plugin-monaco-editor@1.1.0(monaco-editor@0.48.0): + dependencies: + monaco-editor: 0.48.0 + vite-plugin-progress@0.0.7(vite@5.4.1(@types/node@22.4.1)(sass@1.77.8)): dependencies: picocolors: 1.0.1 diff --git a/src/components/common/monaco-editor.vue b/src/components/common/monaco-editor.vue new file mode 100644 index 00000000..9856ad88 --- /dev/null +++ b/src/components/common/monaco-editor.vue @@ -0,0 +1,227 @@ + + + + + + + diff --git a/src/locales/langs/en-us.ts b/src/locales/langs/en-us.ts index c6cddf50..50d696fe 100644 --- a/src/locales/langs/en-us.ts +++ b/src/locales/langs/en-us.ts @@ -18,6 +18,7 @@ const local: App.I18n.Schema = { expandColumn: 'Expand Column', columnSetting: 'Column Setting', config: 'Config', + login: 'Login', confirm: 'Confirm', save: 'Save', delete: 'Delete', @@ -179,7 +180,7 @@ const local: App.I18n.Schema = { }, pwdLogin: { title: 'Password Login', - rememberMe: 'Remember me', + rememberMe: 'Remember password', forgetPassword: 'Forget password?', register: 'Register', otherAccountLogin: 'Other Account Login', diff --git a/src/locales/langs/zh-cn.ts b/src/locales/langs/zh-cn.ts index 34f79652..f78ff5c4 100644 --- a/src/locales/langs/zh-cn.ts +++ b/src/locales/langs/zh-cn.ts @@ -18,6 +18,7 @@ const local: App.I18n.Schema = { expandColumn: '展开列', columnSetting: '列设置', config: '配置', + login: '登录', confirm: '确认', save: '保存', delete: '删除', @@ -179,7 +180,7 @@ const local: App.I18n.Schema = { }, pwdLogin: { title: '密码登录', - rememberMe: '记住我', + rememberMe: '记住密码', forgetPassword: '忘记密码?', register: '注册账号', otherAccountLogin: '其他账号登录', diff --git a/src/service/api/tool/gen.ts b/src/service/api/tool/gen.ts index f1792dc9..588d655c 100644 --- a/src/service/api/tool/gen.ts +++ b/src/service/api/tool/gen.ts @@ -76,7 +76,7 @@ export function fetchSynchGenDbList(tableId: CommonType.IdType) { /** 预览代码 */ export function fetchGetGenPreview(tableId: CommonType.IdType) { - return request({ + return request({ url: `/tool/gen/preview/${tableId}`, method: 'get' }); diff --git a/src/service/request/index.ts b/src/service/request/index.ts index b338a5a7..449afc67 100644 --- a/src/service/request/index.ts +++ b/src/service/request/index.ts @@ -1,7 +1,6 @@ import type { AxiosResponse, InternalAxiosRequestConfig } from 'axios'; import { BACKEND_ERROR_CODE, createFlatRequest } from '@sa/axios'; import { useAuthStore } from '@/store/modules/auth'; -import { $t } from '@/locales'; import { localStg, sessionStg } from '@/utils/storage'; import { getServiceBaseURL } from '@/utils/service'; import { decryptBase64, decryptWithAes, encryptBase64, encryptWithAes, generateAesKey } from '@/utils/crypto'; @@ -58,7 +57,7 @@ export const request = createFlatRequest { setIsInitAuthRoute(true); } else { // if fetch user routes failed, reset store - authStore.logout(); + authStore.resetStore(); } } diff --git a/src/typings/api/tool.api.d.ts b/src/typings/api/tool.api.d.ts index aa4b923c..1b850445 100644 --- a/src/typings/api/tool.api.d.ts +++ b/src/typings/api/tool.api.d.ts @@ -175,6 +175,9 @@ declare namespace Api { Pick & Common.CommonSearchParams >; + /** gen table preview */ + type GenTablePreview = Record; + /** gen table db list */ type GenTableDbList = Common.PaginatingQueryRecord< Common.CommonRecord> diff --git a/src/typings/app.d.ts b/src/typings/app.d.ts index 343562ef..56690924 100644 --- a/src/typings/app.d.ts +++ b/src/typings/app.d.ts @@ -299,6 +299,7 @@ declare namespace App { expandColumn: string; columnSetting: string; config: string; + login: string; confirm: string; save: string; delete: string; diff --git a/src/typings/components.d.ts b/src/typings/components.d.ts index 9df9d3b3..184c3823 100644 --- a/src/typings/components.d.ts +++ b/src/typings/components.d.ts @@ -45,6 +45,7 @@ declare module 'vue' { LookForward: typeof import('./../components/custom/look-forward.vue')['default'] MenuToggler: typeof import('./../components/common/menu-toggler.vue')['default'] MenuTreeSelect: typeof import('./../components/custom/menu-tree-select.vue')['default'] + MonacoEditor: typeof import('./../components/common/monaco-editor.vue')['default'] NAlert: typeof import('naive-ui')['NAlert'] NBreadcrumb: typeof import('naive-ui')['NBreadcrumb'] NBreadcrumbItem: typeof import('naive-ui')['NBreadcrumbItem'] diff --git a/src/typings/elegant-router.d.ts b/src/typings/elegant-router.d.ts index 5279b28a..15c63960 100644 --- a/src/typings/elegant-router.d.ts +++ b/src/typings/elegant-router.d.ts @@ -161,7 +161,7 @@ declare module "@elegant-router/types" { component: `view.${K}`; } : never; - + /** * the center level route */ @@ -184,7 +184,7 @@ declare module "@elegant-router/types" { children: (CenterLevelRoute> | LastLevelRoute>)[]; } : never; - + /** * the custom first level route */ diff --git a/src/typings/storage.d.ts b/src/typings/storage.d.ts index 9f462f4a..16b06e63 100644 --- a/src/typings/storage.d.ts +++ b/src/typings/storage.d.ts @@ -40,5 +40,7 @@ declare namespace StorageType { layout: UnionKey.ThemeLayoutMode; siderCollapse: boolean; }; + /** The login form rember */ + loginRember: Api.Auth.PwdLoginForm; } } diff --git a/src/views/_builtin/login/modules/pwd-login.vue b/src/views/_builtin/login/modules/pwd-login.vue index 8619eee0..1d470eb7 100644 --- a/src/views/_builtin/login/modules/pwd-login.vue +++ b/src/views/_builtin/login/modules/pwd-login.vue @@ -8,6 +8,7 @@ import { useRouterPush } from '@/hooks/common/router'; import { useFormRules, useNaiveForm } from '@/hooks/common/form'; import { useAuthStore } from '@/store/modules/auth'; import { fetchCaptchaCode, fetchTenantList } from '@/service/api'; +import { localStg } from '@/utils/storage'; defineOptions({ name: 'PwdLogin' @@ -26,8 +27,8 @@ const tenantOption = ref([]); const model: Api.Auth.PwdLoginForm = reactive({ tenantId: '000000', - username: 'admin', - password: 'admin123' + username: '', + password: '' }); type RuleKey = Extract; @@ -48,6 +49,14 @@ const rules = computed>(() => { async function handleSubmit() { await validate(); + // 勾选了需要记住密码设置在 localStorage 中设置记住用户名和密码 + if (remberMe.value) { + const { tenantId, username, password } = model; + localStg.set('loginRember', { tenantId, username, password }); + } else { + // 否则移除 + localStg.remove('loginRember'); + } try { await authStore.login(model); } catch (error) { @@ -57,15 +66,14 @@ async function handleSubmit() { async function handleFetchTenantList() { const { data, error } = await fetchTenantList(); - if (!error) { - tenantEnabled.value = data.tenantEnabled; - tenantOption.value = data.voList.map(tenant => { - return { - label: tenant.companyName, - value: tenant.tenantId - }; - }); - } + if (error) return; + tenantEnabled.value = data.tenantEnabled; + tenantOption.value = data.voList.map(tenant => { + return { + label: tenant.companyName, + value: tenant.tenantId + }; + }); } handleFetchTenantList(); @@ -84,6 +92,15 @@ async function handleFetchCaptchaCode() { } handleFetchCaptchaCode(); + +function handleLoginRember() { + const loginRember = localStg.get('loginRember'); + if (!loginRember) return; + remberMe.value = true; + Object.assign(model, loginRember); +} + +handleLoginRember();