mirror of
https://github.com/vbenjs/gf-vben-admin.git
synced 2025-01-23 20:00:19 +08:00
wip: support multilingual configuration
This commit is contained in:
parent
3a651767fe
commit
8882d4e7ea
@ -1,96 +0,0 @@
|
||||
// Modified from
|
||||
// https://github.com/luxueyan/vite-transform-globby-import/blob/master/src/index.ts
|
||||
|
||||
// TODO Currently, it is not possible to monitor file addition and deletion. The content has been changed, the cache problem?
|
||||
import { join } from 'path';
|
||||
import { lstatSync } from 'fs';
|
||||
import glob from 'glob';
|
||||
import { createResolver, Resolver } from 'vite/dist/node/resolver.js';
|
||||
import { Transform } from 'vite/dist/node/transform.js';
|
||||
|
||||
const modulesDir: string = join(process.cwd(), '/node_modules/');
|
||||
|
||||
interface SharedConfig {
|
||||
root?: string;
|
||||
alias?: Record<string, string>;
|
||||
resolvers?: Resolver[];
|
||||
}
|
||||
|
||||
function template(template: string) {
|
||||
return (data: { [x: string]: any }) => {
|
||||
return template.replace(/#([^#]+)#/g, (_, g1) => data[g1] || g1);
|
||||
};
|
||||
}
|
||||
|
||||
const globbyTransform = function (config: SharedConfig): Transform {
|
||||
const resolver = createResolver(
|
||||
config.root || process.cwd(),
|
||||
config.resolvers || [],
|
||||
config.alias || {}
|
||||
);
|
||||
const cache = new Map();
|
||||
|
||||
const urlMap = new Map();
|
||||
return {
|
||||
test({ path }) {
|
||||
const filePath = path.replace('\u0000', ''); // why some path startsWith '\u0000'?
|
||||
try {
|
||||
return (
|
||||
!filePath.startsWith(modulesDir) &&
|
||||
/\.(vue|js|jsx|ts|tsx)$/.test(filePath) &&
|
||||
lstatSync(filePath).isFile()
|
||||
);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
transform({ code, path, isBuild }) {
|
||||
let result = cache.get(path);
|
||||
if (!result) {
|
||||
const reg = /import\s+([\w\s{}*]+)\s+from\s+(['"])globby(\?path)?!([^'"]+)\2/g;
|
||||
const match = code.match(reg);
|
||||
if (!match) return code;
|
||||
const lastImport = urlMap.get(path);
|
||||
if (lastImport && match) {
|
||||
code = code.replace(lastImport, match[0]);
|
||||
}
|
||||
result = code.replace(reg, (_, g1, g2, g3, g4) => {
|
||||
const filePath = path.replace('\u0000', ''); // why some path startsWith '\u0000'?
|
||||
// resolve path
|
||||
const resolvedFilePath = g4.startsWith('.')
|
||||
? resolver.resolveRelativeRequest(filePath, g4)
|
||||
: { pathname: resolver.requestToFile(g4) };
|
||||
const files = glob.sync(resolvedFilePath.pathname, { dot: true });
|
||||
let templateStr = 'import #name# from #file#'; // import default
|
||||
let name = g1;
|
||||
const m = g1.match(/\{\s*(\w+)(\s+as\s+(\w+))?\s*\}/); // import module
|
||||
const m2 = g1.match(/\*\s+as\s+(\w+)/); // import * as all module
|
||||
if (m) {
|
||||
templateStr = `import { ${m[1]} as #name# } from #file#`;
|
||||
name = m[3] || m[1];
|
||||
} else if (m2) {
|
||||
templateStr = 'import * as #name# from #file#';
|
||||
name = m2[1];
|
||||
}
|
||||
const temRender = template(templateStr);
|
||||
|
||||
const groups: Array<string>[] = [];
|
||||
const replaceFiles = files.map((f, i) => {
|
||||
const file = g2 + resolver.fileToRequest(f) + g2;
|
||||
groups.push([name + i, file]);
|
||||
return temRender({ name: name + i, file });
|
||||
});
|
||||
urlMap.set(path, replaceFiles.join('\n'));
|
||||
return (
|
||||
replaceFiles.join('\n') +
|
||||
(g3 ? '\n' + groups.map((v) => `${v[0]}._path = ${v[1]}`).join('\n') : '') +
|
||||
`\nconst ${name} = { ${groups.map((v) => v[0]).join(',')} }\n`
|
||||
);
|
||||
});
|
||||
if (isBuild) cache.set(path, result);
|
||||
}
|
||||
return result;
|
||||
},
|
||||
};
|
||||
};
|
||||
export default globbyTransform;
|
@ -1,7 +1,6 @@
|
||||
// Used to import all files under `src/views`
|
||||
|
||||
// The built-in dynamic import of vite cannot meet the needs of importing all files under views
|
||||
|
||||
// Special usage ,Only for this project
|
||||
import glob from 'glob';
|
||||
import { Transform } from 'vite/dist/node/transform.js';
|
||||
|
||||
@ -28,7 +27,6 @@ const dynamicImportTransform = function (env: any = {}): Transform {
|
||||
return code;
|
||||
}
|
||||
|
||||
// if (!isBuild) return code;
|
||||
// Only convert the dir
|
||||
try {
|
||||
const files = glob.sync('src/views/**/**.{vue,tsx}', { cwd: process.cwd() });
|
201
build/vite/plugin/transform/globby/index.ts
Normal file
201
build/vite/plugin/transform/globby/index.ts
Normal file
@ -0,0 +1,201 @@
|
||||
// Modified from
|
||||
// https://github.com/luxueyan/vite-transform-globby-import/blob/master/src/index.ts
|
||||
|
||||
// TODO Deleting files requires re-running the project
|
||||
import { join } from 'path';
|
||||
import { lstatSync } from 'fs';
|
||||
import glob from 'glob';
|
||||
import globrex from 'globrex';
|
||||
import dotProp from 'dot-prop';
|
||||
import { createResolver, Resolver } from 'vite/dist/node/resolver.js';
|
||||
import { Transform } from 'vite/dist/node/transform.js';
|
||||
|
||||
const modulesDir: string = join(process.cwd(), '/node_modules/');
|
||||
|
||||
interface SharedConfig {
|
||||
root?: string;
|
||||
alias?: Record<string, string>;
|
||||
resolvers?: Resolver[];
|
||||
|
||||
includes?: string[];
|
||||
}
|
||||
|
||||
function template(template: string) {
|
||||
return (data: { [x: string]: any }) => {
|
||||
return template.replace(/#([^#]+)#/g, (_, g1) => data[g1] || g1);
|
||||
};
|
||||
}
|
||||
|
||||
// TODO support hmr
|
||||
function hmr(isBuild = false) {
|
||||
if (isBuild) return '';
|
||||
return `
|
||||
if (import.meta.hot) {
|
||||
import.meta.hot.accept();
|
||||
}`;
|
||||
}
|
||||
|
||||
// handle includes
|
||||
function fileInclude(includes: string | string[] | undefined, filePath: string) {
|
||||
return !includes || !Array.isArray(includes)
|
||||
? true
|
||||
: includes.some((item) => filePath.startsWith(item));
|
||||
}
|
||||
|
||||
// Bare exporter
|
||||
function compareString(modify: any, data: string[][]) {
|
||||
return modify ? '\n' + data.map((v) => `${v[0]}._path = ${v[1]}`).join('\n') : '';
|
||||
}
|
||||
|
||||
function varTemplate(data: string[][], name: string) {
|
||||
//prepare deep data (for locales)
|
||||
let deepData: Record<string, object | string> = {};
|
||||
let hasDeepData = false;
|
||||
|
||||
//data modify
|
||||
data.map((v) => {
|
||||
//check for has deep data
|
||||
if (v[0].includes('/')) {
|
||||
hasDeepData = true;
|
||||
}
|
||||
|
||||
// lastKey is a data
|
||||
let pathValue = v[0].replace(/\//g, '.').split('.');
|
||||
let lastKey: string | undefined = pathValue.pop();
|
||||
|
||||
let deepValue: Record<any, any> = {};
|
||||
if (lastKey) {
|
||||
deepValue[lastKey.replace('_' + pathValue[0], '')] = lastKey;
|
||||
}
|
||||
|
||||
// Set Deep Value
|
||||
deepValue = Object.assign(deepValue, dotProp.get(deepData, pathValue.join('.')));
|
||||
dotProp.set(deepData, pathValue.join('.'), deepValue);
|
||||
});
|
||||
|
||||
if (hasDeepData) {
|
||||
return `const ${name} = ` + JSON.stringify(deepData).replace(/\"|\'/g, '');
|
||||
}
|
||||
|
||||
return `const ${name} = { ${data.map((v) => v[0]).join(',')} }`;
|
||||
}
|
||||
|
||||
const globTransform = function (config: SharedConfig): Transform {
|
||||
const resolver = createResolver(
|
||||
config.root || process.cwd(),
|
||||
config.resolvers || [],
|
||||
config.alias || {}
|
||||
);
|
||||
const { includes } = config;
|
||||
const cache = new Map();
|
||||
const urlMap = new Map();
|
||||
return {
|
||||
test({ path }) {
|
||||
const filePath = path.replace('\u0000', ''); // why some path startsWith '\u0000'?
|
||||
|
||||
try {
|
||||
return (
|
||||
!filePath.startsWith(modulesDir) &&
|
||||
/\.(vue|js|jsx|ts|tsx)$/.test(filePath) &&
|
||||
fileInclude(includes, filePath) &&
|
||||
lstatSync(filePath).isFile()
|
||||
);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
transform({ code, path, isBuild }) {
|
||||
let result = cache.get(path);
|
||||
if (!result) {
|
||||
const reg = /import\s+([\w\s{}*]+)\s+from\s+(['"])globby(\?locale)?(\?path)?!([^'"]+)\2/g;
|
||||
const match = code.match(reg);
|
||||
if (!match) return code;
|
||||
const lastImport = urlMap.get(path);
|
||||
if (lastImport && match) {
|
||||
code = code.replace(lastImport, match[0]);
|
||||
}
|
||||
result = code.replace(
|
||||
reg,
|
||||
(
|
||||
_,
|
||||
// variable to export
|
||||
exportName,
|
||||
// bare export or not
|
||||
bareExporter,
|
||||
// is locale import
|
||||
isLocale,
|
||||
// inject _path attr
|
||||
injectPath,
|
||||
// path export
|
||||
globPath
|
||||
) => {
|
||||
const filePath = path.replace('\u0000', ''); // why some path startsWith '\u0000'?
|
||||
// resolve path
|
||||
|
||||
const resolvedFilePath = globPath.startsWith('.')
|
||||
? resolver.resolveRelativeRequest(filePath, globPath)
|
||||
: { pathname: resolver.requestToFile(globPath) };
|
||||
|
||||
const files = glob.sync(resolvedFilePath.pathname, { dot: true });
|
||||
|
||||
let templateStr = 'import #name# from #file#'; // import default
|
||||
let name = exportName;
|
||||
const m = exportName.match(/\{\s*(\w+)(\s+as\s+(\w+))?\s*\}/); // import module
|
||||
const m2 = exportName.match(/\*\s+as\s+(\w+)/); // import * as all module
|
||||
if (m) {
|
||||
templateStr = `import { ${m[1]} as #name# } from #file#`;
|
||||
name = m[3] || m[1];
|
||||
} else if (m2) {
|
||||
templateStr = 'import * as #name# from #file#';
|
||||
name = m2[1];
|
||||
}
|
||||
|
||||
const templateRender = template(templateStr);
|
||||
|
||||
const groups: Array<string>[] = [];
|
||||
const replaceFiles = files.map((f, i) => {
|
||||
const fileNameWithAlias = resolver.fileToRequest(f);
|
||||
|
||||
const file = bareExporter + fileNameWithAlias + bareExporter;
|
||||
|
||||
if (isLocale) {
|
||||
const globrexRes = globrex(globPath, { extended: true, globstar: true });
|
||||
|
||||
// Get segments for files like an en/system ch/modules for:
|
||||
// ['en', 'system'] ['ch', 'modules']
|
||||
const matchedGroups = globrexRes.regex.exec(fileNameWithAlias);
|
||||
|
||||
if (matchedGroups && matchedGroups.length) {
|
||||
const matchedSegments = matchedGroups[1]; //first everytime "Full Match"
|
||||
const name = matchedGroups[2] + '_' + matchedSegments.split('/').shift();
|
||||
//send deep way like an (en/modules/system/dashboard) into groups
|
||||
groups.push([matchedSegments + name, file]);
|
||||
return templateRender({
|
||||
name,
|
||||
file,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
groups.push([name + i, file]);
|
||||
return templateRender({ name: name + i, file });
|
||||
}
|
||||
});
|
||||
// save in memory used result
|
||||
const filesJoined = replaceFiles.join('\n');
|
||||
|
||||
urlMap.set(path, filesJoined);
|
||||
return [
|
||||
filesJoined,
|
||||
compareString(injectPath, groups),
|
||||
varTemplate(groups, name),
|
||||
'',
|
||||
].join('\n');
|
||||
}
|
||||
);
|
||||
if (isBuild) cache.set(path, result);
|
||||
}
|
||||
return `${result}${hmr(isBuild)}`;
|
||||
},
|
||||
};
|
||||
};
|
||||
export default globTransform;
|
@ -22,7 +22,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@iconify/iconify": "^2.0.0-rc.2",
|
||||
"@vueuse/core": "4.0.0-beta.41",
|
||||
"@vueuse/core": "4.0.0-rc.3",
|
||||
"ant-design-vue": "2.0.0-beta.15",
|
||||
"apexcharts": "3.22.0",
|
||||
"axios": "^0.21.0",
|
||||
@ -35,7 +35,7 @@
|
||||
"qrcode": "^1.4.4",
|
||||
"vditor": "^3.6.2",
|
||||
"vue": "^3.0.2",
|
||||
"vue-i18n": "^9.0.0-beta.7",
|
||||
"vue-i18n": "^9.0.0-beta.8",
|
||||
"vue-router": "^4.0.0-rc.3",
|
||||
"vuex": "^4.0.0-rc.1",
|
||||
"vuex-module-decorators": "^1.0.1",
|
||||
@ -50,6 +50,7 @@
|
||||
"@purge-icons/generated": "^0.4.1",
|
||||
"@types/echarts": "^4.9.1",
|
||||
"@types/fs-extra": "^9.0.4",
|
||||
"@types/globrex": "^0.1.0",
|
||||
"@types/koa-static": "^4.0.1",
|
||||
"@types/lodash-es": "^4.17.3",
|
||||
"@types/mockjs": "^1.0.3",
|
||||
@ -68,6 +69,7 @@
|
||||
"conventional-changelog-cli": "^2.1.1",
|
||||
"conventional-changelog-custom-config": "^0.3.1",
|
||||
"cross-env": "^7.0.2",
|
||||
"dot-prop": "^6.0.0",
|
||||
"dotenv": "^8.2.0",
|
||||
"eslint": "^7.13.0",
|
||||
"eslint-config-prettier": "^6.15.0",
|
||||
@ -75,6 +77,7 @@
|
||||
"eslint-plugin-vue": "^7.1.0",
|
||||
"esno": "^0.2.4",
|
||||
"fs-extra": "^9.0.1",
|
||||
"globrex": "^0.1.2",
|
||||
"husky": "^4.3.0",
|
||||
"koa-static": "^5.0.0",
|
||||
"less": "^3.12.2",
|
||||
|
21
src/hooks/web/useLocale.ts
Normal file
21
src/hooks/web/useLocale.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import type { LocaleType } from '/@/locales/types';
|
||||
import { appStore } from '/@/store/modules/app';
|
||||
|
||||
export function useLocale() {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function getLocale(): string {
|
||||
return appStore.getProjectConfig.locale;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param locale
|
||||
*/
|
||||
async function changeLocale(locale: LocaleType): Promise<void> {
|
||||
appStore.commitProjectConfigState({ locale: locale });
|
||||
}
|
||||
|
||||
return { getLocale, changeLocale };
|
||||
}
|
3
src/locales/index.ts
Normal file
3
src/locales/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import messages from 'globby?locale!/@/locales/lang/**/*.@(ts)';
|
||||
|
||||
export default messages;
|
3
src/locales/lang/en/routes/menus/dashboard.ts
Normal file
3
src/locales/lang/en/routes/menus/dashboard.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export default {
|
||||
someentry: 'some text',
|
||||
};
|
3
src/locales/lang/en/system/basic.ts
Normal file
3
src/locales/lang/en/system/basic.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export default {
|
||||
some: 'Get Out',
|
||||
};
|
3
src/locales/lang/en/system/login.ts
Normal file
3
src/locales/lang/en/system/login.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export default {
|
||||
button: 'Login',
|
||||
};
|
3
src/locales/lang/ru/routes/menus/dashboard.ts
Normal file
3
src/locales/lang/ru/routes/menus/dashboard.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export default {
|
||||
someentry: 'some text',
|
||||
};
|
3
src/locales/lang/ru/system/basic.ts
Normal file
3
src/locales/lang/ru/system/basic.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export default {
|
||||
some: 'Get Out',
|
||||
};
|
7
src/locales/lang/ru/system/login.ts
Normal file
7
src/locales/lang/ru/system/login.ts
Normal file
@ -0,0 +1,7 @@
|
||||
export default {
|
||||
button: 'Login',
|
||||
validation: {
|
||||
account: 'Required Field account',
|
||||
password: 'Required Field password',
|
||||
},
|
||||
};
|
3
src/locales/lang/zhCN/routes/menus/dashboard.ts
Normal file
3
src/locales/lang/zhCN/routes/menus/dashboard.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export default {
|
||||
someentry: '一些文本',
|
||||
};
|
3
src/locales/lang/zhCN/system/basic.ts
Normal file
3
src/locales/lang/zhCN/system/basic.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export default {
|
||||
some: '出去',
|
||||
};
|
3
src/locales/lang/zhCN/system/login.ts
Normal file
3
src/locales/lang/zhCN/system/login.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export default {
|
||||
button: '登录',
|
||||
};
|
1
src/locales/types.ts
Normal file
1
src/locales/types.ts
Normal file
@ -0,0 +1 @@
|
||||
export type LocaleType = 'zhCN' | 'en' | 'ru' | 'ja';
|
@ -5,6 +5,7 @@ import { setupStore } from '/@/store';
|
||||
import { setupAntd } from '/@/setup/ant-design-vue';
|
||||
import { setupErrorHandle } from '/@/setup/error-handle';
|
||||
import { setupGlobDirectives } from '/@/setup/directives';
|
||||
import { setupI18n } from '/@/setup/i18n';
|
||||
|
||||
import { setupProdMockServer } from '../mock/_createProductionServer';
|
||||
import { setApp } from '/@/setup/App';
|
||||
@ -15,11 +16,16 @@ import { isDevMode, isProdMode, isUseMock } from '/@/utils/env';
|
||||
|
||||
import '/@/design/index.less';
|
||||
|
||||
import '/@/locales/index';
|
||||
|
||||
const app = createApp(App);
|
||||
|
||||
// Configure component library
|
||||
setupAntd(app);
|
||||
|
||||
// Multilingual configuration
|
||||
setupI18n(app);
|
||||
|
||||
// Configure routing
|
||||
setupRouter(app);
|
||||
|
||||
|
@ -7,6 +7,7 @@ import { isProdMode } from '/@/utils/env';
|
||||
|
||||
// ! You need to clear the browser cache after the change
|
||||
const setting: ProjectConfig = {
|
||||
locale: 'en',
|
||||
// color
|
||||
// TODO 主题色
|
||||
themeColor: primaryColor,
|
||||
|
35
src/setup/i18n/index.ts
Normal file
35
src/setup/i18n/index.ts
Normal file
@ -0,0 +1,35 @@
|
||||
import type { App } from 'vue';
|
||||
import type { I18n, Locale, I18nOptions } from 'vue-i18n';
|
||||
|
||||
import { createI18n } from 'vue-i18n';
|
||||
import localeMessages from '/@/locales';
|
||||
import { useLocale } from '/@/hooks/web/useLocale';
|
||||
|
||||
const { getLocale } = useLocale();
|
||||
|
||||
const localeData: I18nOptions = {
|
||||
legacy: false,
|
||||
locale: getLocale(),
|
||||
// TODO: setting fallback inside settings
|
||||
fallbackLocale: 'en',
|
||||
messages: localeMessages,
|
||||
// availableLocales: ['ru'],
|
||||
sync: true, //If you don’t want to inherit locale from global scope, you need to set sync of i18n component option to false.
|
||||
silentTranslationWarn: false, // true - warning off
|
||||
silentFallbackWarn: true,
|
||||
};
|
||||
|
||||
let i18n: I18n;
|
||||
|
||||
// setup i18n instance with glob
|
||||
export function setupI18n(app: App) {
|
||||
i18n = createI18n(localeData) as I18n;
|
||||
setI18nLanguage(getLocale());
|
||||
app.use(i18n);
|
||||
}
|
||||
|
||||
export function setI18nLanguage(locale: Locale): void {
|
||||
// @ts-ignore
|
||||
i18n.global.locale.value = locale;
|
||||
// i18n.global.setLocaleMessage(locale, messages);
|
||||
}
|
@ -1,16 +1,19 @@
|
||||
import type { App } from 'vue';
|
||||
import { createStore, createLogger, Plugin } from 'vuex';
|
||||
import {
|
||||
createStore,
|
||||
// createLogger, Plugin
|
||||
} from 'vuex';
|
||||
import { config } from 'vuex-module-decorators';
|
||||
import { isDevMode } from '/@/utils/env';
|
||||
|
||||
config.rawError = true;
|
||||
const isDev = isDevMode();
|
||||
const plugins: Plugin<any>[] = isDev ? [createLogger()] : [];
|
||||
// const plugins: Plugin<any>[] = isDev ? [createLogger()] : [];
|
||||
|
||||
const store = createStore({
|
||||
// modules: {},
|
||||
strict: isDev,
|
||||
plugins,
|
||||
// plugins,
|
||||
});
|
||||
|
||||
export function setupStore(app: App<Element>) {
|
||||
|
3
src/types/config.d.ts
vendored
3
src/types/config.d.ts
vendored
@ -1,7 +1,7 @@
|
||||
// 左侧菜单, 顶部菜单
|
||||
import { MenuTypeEnum, MenuModeEnum, TriggerEnum } from '/@/enums/menuEnum';
|
||||
import { ContentEnum, PermissionModeEnum, ThemeEnum, RouterTransitionEnum } from '/@/enums/appEnum';
|
||||
|
||||
import type { LocaleType } from '/@/locales/types';
|
||||
export interface MessageSetting {
|
||||
title: string;
|
||||
// 取消按钮的文字,
|
||||
@ -55,6 +55,7 @@ export interface HeaderSetting {
|
||||
showNotice: boolean;
|
||||
}
|
||||
export interface ProjectConfig {
|
||||
locale: LocaleType;
|
||||
// header背景色
|
||||
headerBgColor: string;
|
||||
// 左侧菜单背景色
|
||||
|
2
src/types/module.d.ts
vendored
2
src/types/module.d.ts
vendored
@ -4,4 +4,6 @@ declare module 'globby!/@/router/routes/modules/**/*.@(ts)';
|
||||
|
||||
declare module 'globby!/@/router/menus/modules/**/*.@(ts)';
|
||||
|
||||
declare module 'globby?locale!/@/locales/lang/**/*.@(ts)';
|
||||
|
||||
declare const React: string;
|
||||
|
@ -11,14 +11,14 @@
|
||||
|
||||
<a-form class="mx-auto mt-10" :model="formData" :rules="formRules" ref="formRef">
|
||||
<a-form-item name="account">
|
||||
<a-input size="large" v-model:value="formData.account" placeholder="Username: vben" />
|
||||
<a-input size="large" v-model:value="formData.account" placeholder="username: vben" />
|
||||
</a-form-item>
|
||||
<a-form-item name="password">
|
||||
<a-input-password
|
||||
size="large"
|
||||
visibilityToggle
|
||||
v-model:value="formData.password"
|
||||
placeholder="Password: 123456"
|
||||
placeholder="password: 123456"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
@ -28,13 +28,13 @@
|
||||
<a-row>
|
||||
<a-col :span="12">
|
||||
<a-form-item>
|
||||
<!-- 未做逻辑,需要自行处理 -->
|
||||
<!-- No logic, you need to deal with it yourself -->
|
||||
<a-checkbox v-model:checked="autoLogin" size="small">自动登录</a-checkbox>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item :style="{ 'text-align': 'right' }">
|
||||
<!-- 未做逻辑,需要自行处理 -->
|
||||
<!-- No logic, you need to deal with it yourself -->
|
||||
<a-button type="link" size="small">忘记密码</a-button>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
@ -47,7 +47,7 @@
|
||||
:block="true"
|
||||
@click="login"
|
||||
:loading="formState.loading"
|
||||
>登录</a-button
|
||||
>{{ t('system.login.button') }}</a-button
|
||||
>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
@ -57,20 +57,15 @@
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import {
|
||||
defineComponent,
|
||||
reactive,
|
||||
ref,
|
||||
unref,
|
||||
toRaw,
|
||||
// computed
|
||||
} from 'vue';
|
||||
import { defineComponent, reactive, ref, unref, toRaw } from 'vue';
|
||||
import { Checkbox } from 'ant-design-vue';
|
||||
|
||||
import Button from '/@/components/Button/index.vue';
|
||||
// import { BasicDragVerify, DragVerifyActionType } from '/@/components/Verify/index';
|
||||
|
||||
import { userStore } from '/@/store/modules/user';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
// import { appStore } from '/@/store/modules/app';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { useSetting } from '/@/hooks/core/useSetting';
|
||||
@ -139,7 +134,7 @@
|
||||
formState.loading = false;
|
||||
}
|
||||
}
|
||||
|
||||
const { t } = useI18n();
|
||||
return {
|
||||
formRef,
|
||||
// verifyRef,
|
||||
@ -151,6 +146,7 @@
|
||||
// openLoginVerify: openLoginVerifyRef,
|
||||
title: globSetting && globSetting.title,
|
||||
logo,
|
||||
t,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
@ -4,8 +4,9 @@ import { resolve } from 'path';
|
||||
|
||||
import { modifyVars } from './build/config/lessModifyVars';
|
||||
import { createProxy } from './build/vite/proxy';
|
||||
import globbyTransform from './build/vite/plugin/context/transform';
|
||||
import dynamicImportTransform from './build/vite/plugin/dynamicImport/index';
|
||||
|
||||
import globbyTransform from './build/vite/plugin/transform/globby';
|
||||
import dynamicImportTransform from './build/vite/plugin/transform/dynamic-import';
|
||||
|
||||
import { isDevFn, loadEnv } from './build/utils';
|
||||
|
||||
@ -111,6 +112,11 @@ const viteConfig: UserConfig = {
|
||||
},
|
||||
define: {
|
||||
__VERSION__: pkg.version,
|
||||
// use vue-i18-next
|
||||
// Suppress warning
|
||||
__VUE_I18N_LEGACY_API__: false,
|
||||
__VUE_I18N_FULL_INSTALL__: false,
|
||||
__INTLIFY_PROD_DEVTOOLS__: false,
|
||||
},
|
||||
cssPreprocessOptions: {
|
||||
less: {
|
||||
@ -135,5 +141,13 @@ const viteConfig: UserConfig = {
|
||||
|
||||
export default {
|
||||
...viteConfig,
|
||||
transforms: [globbyTransform(viteConfig), dynamicImportTransform(viteEnv)],
|
||||
transforms: [
|
||||
globbyTransform({
|
||||
resolvers: viteConfig.resolvers,
|
||||
root: viteConfig.root,
|
||||
alias: viteConfig.alias,
|
||||
includes: [resolve('src/router'), resolve('src/locales')],
|
||||
}),
|
||||
dynamicImportTransform(viteEnv),
|
||||
],
|
||||
} as UserConfig;
|
||||
|
43
yarn.lock
43
yarn.lock
@ -1323,6 +1323,11 @@
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/globrex@^0.1.0":
|
||||
version "0.1.0"
|
||||
resolved "https://registry.npmjs.org/@types/globrex/-/globrex-0.1.0.tgz#baf4ac8e36947017612c01fde7c7b641dc0b6c89"
|
||||
integrity sha512-aBkxDgp/UbnluE+CIT3V3PoNewwOlLCzXSF3ipD86Slv8xVjwxrDAfSGbsfGgMzPo/fEMPXc+gNUJbtiugwfoA==
|
||||
|
||||
"@types/http-assert@*":
|
||||
version "1.5.1"
|
||||
resolved "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.1.tgz#d775e93630c2469c2f980fc27e3143240335db3b"
|
||||
@ -1732,18 +1737,18 @@
|
||||
vscode-languageserver-textdocument "^1.0.1"
|
||||
vscode-uri "^2.1.2"
|
||||
|
||||
"@vueuse/core@4.0.0-beta.41":
|
||||
version "4.0.0-beta.41"
|
||||
resolved "https://registry.npmjs.org/@vueuse/core/-/core-4.0.0-beta.41.tgz#0058aed5ade75ae2866283498009ad5172cbae84"
|
||||
integrity sha512-CgUih65PzYScorm1S4F93e6XXm+qxA8GrRLOSB1kXaqtP6vXedwkBxKkNEYNACx4reL4VEHqM/BrM6FajXkQUg==
|
||||
"@vueuse/core@4.0.0-rc.3":
|
||||
version "4.0.0-rc.3"
|
||||
resolved "https://registry.npmjs.org/@vueuse/core/-/core-4.0.0-rc.3.tgz#5381ca657e10df596cd7027fc5c96b2d4b3a090c"
|
||||
integrity sha512-dQ/FZgo0z7kBFOvDWxuzaUrmuO8X1AlQk17e3PU1TVtG2Uu+mCvjPNbuvI2fjhTjl5rzPJawwoU2WZFj+nlFvw==
|
||||
dependencies:
|
||||
"@vueuse/shared" "4.0.0-beta.41"
|
||||
"@vueuse/shared" "4.0.0-rc.3"
|
||||
vue-demi latest
|
||||
|
||||
"@vueuse/shared@4.0.0-beta.41":
|
||||
version "4.0.0-beta.41"
|
||||
resolved "https://registry.npmjs.org/@vueuse/shared/-/shared-4.0.0-beta.41.tgz#395782ea2e580f1fc9488d25c89bd09f70170b25"
|
||||
integrity sha512-dqnuEPPC3OUJ6L6rhMiOCuPWIR698DtdwOydwCZBISsG2V6gZ2QFND6xtRwLib6/lhUMYVYPwIz3hPjlx7BIzw==
|
||||
"@vueuse/shared@4.0.0-rc.3":
|
||||
version "4.0.0-rc.3"
|
||||
resolved "https://registry.npmjs.org/@vueuse/shared/-/shared-4.0.0-rc.3.tgz#42fb56fed3779f3b8a17a82c16a364bad20d01b7"
|
||||
integrity sha512-VY0x/XxpeTMHp/0FDiv1cgUUxkJGQl7liiM2AjR/J7+Ys/2Y2dijD5cAKViq9FGUPQQsOcLptMvMvUsDMoN4DA==
|
||||
dependencies:
|
||||
vue-demi latest
|
||||
|
||||
@ -3222,6 +3227,13 @@ dot-prop@^5.1.0:
|
||||
dependencies:
|
||||
is-obj "^2.0.0"
|
||||
|
||||
dot-prop@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.0.tgz#bd579fd704d970981c4b05de591db648959f2ebb"
|
||||
integrity sha512-xCbB8IN3IT+tdgoEPOnJmYTNJDrygGFOmiQEiVa5eAD+JEB1vTgMNhVGRnN5Eex/6amck7cdcrixb1qN9Go+GQ==
|
||||
dependencies:
|
||||
is-obj "^2.0.0"
|
||||
|
||||
dotenv-expand@^5.1.0:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0"
|
||||
@ -4092,6 +4104,11 @@ globjoin@^0.1.4:
|
||||
resolved "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz#2f4494ac8919e3767c5cbb691e9f463324285d43"
|
||||
integrity sha1-L0SUrIkZ43Z8XLtpHp9GMyQoXUM=
|
||||
|
||||
globrex@^0.1.2:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz#dd5d9ec826232730cd6793a5e33a9302985e6098"
|
||||
integrity sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==
|
||||
|
||||
gonzales-pe@^4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz#fe9dec5f3c557eead09ff868c65826be54d067b3"
|
||||
@ -8167,10 +8184,10 @@ vue-eslint-parser@^7.1.1:
|
||||
esquery "^1.0.1"
|
||||
lodash "^4.17.15"
|
||||
|
||||
vue-i18n@^9.0.0-beta.7:
|
||||
version "9.0.0-beta.7"
|
||||
resolved "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.0.0-beta.7.tgz#f6fad5b4be218018aab4797f80dd2a95ee5236f9"
|
||||
integrity sha512-hFl0XnV91P/4UyWvHYvdYxuk3GRnKIW9zXAm6hrUU4mOIwpqchi7jVQva2TJLr52Mpsu4zYXmzL1h5pgrKmCfQ==
|
||||
vue-i18n@^9.0.0-beta.8:
|
||||
version "9.0.0-beta.8"
|
||||
resolved "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.0.0-beta.8.tgz#92282d5b5e0e6f15cc04943ce11bf49db610468f"
|
||||
integrity sha512-tViSN96jLi0AKvAVi4twcYYN5Ld++SqN1/140ua+YWm/iRbO2M0rAcsZ7e6/4LTm6Pd1ldSwWihSuv2bSQmlnw==
|
||||
dependencies:
|
||||
source-map "0.6.1"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user