提交 962f90de 编写于 作者: V vben

feat: support vscode i18n-ally plugin

上级 41a4b827
......@@ -5,8 +5,8 @@
"stylelint.vscode-stylelint",
"DavidAnson.vscode-markdownlint",
"esbenp.prettier-vscode",
"mrmlnc.vscode-scss",
"mrmlnc.vscode-less",
"antfu.i18n-ally",
"cpylua.language-postcss",
"Orta.vscode-jest",
"antfu.iconify",
......
......@@ -10,14 +10,13 @@
"editor.smoothScrolling": true,
"editor.cursorBlinking": "phase",
"editor.cursorSmoothCaretAnimation": true,
"editor.detectIndentation": false, // vscode默认启用了根据文件类型自动设置tabsize的选项
"editor.detectIndentation": false,
"diffEditor.ignoreTrimWhitespace": false,
"editor.formatOnPaste": true, //自动格式化粘贴的内容
"editor.formatOnSave": true, //保存自动格式化
"editor.formatOnPaste": true,
"editor.formatOnSave": true,
"editor.suggestSelection": "first",
"editor.trimAutoWhitespace": true,
"editor.quickSuggestions": {
// 快速提示
"other": true,
"comments": true,
"strings": true
......@@ -25,41 +24,33 @@
//===========================================
//============= Other =======================
//===========================================
"breadcrumbs.enabled": true, // 启用/禁用导航路径
"open-in-browser.default": "chrome", // 默认浏览器
"breadcrumbs.enabled": true,
"open-in-browser.default": "chrome",
//===========================================
//============= emmet =======================
//===========================================
"emmet.triggerExpansionOnTab": true, // 配置emmet是否启用tab展开缩写
"emmet.triggerExpansionOnTab": true,
"emmet.showAbbreviationSuggestions": true,
"emmet.showExpandedAbbreviation": "always",
"emmet.syntaxProfiles": {
// 配置emmet对文件类型的支持,比如vue后缀文件按照html文件来进行emmet扩写
"vue-html": "html",
"vue": "html",
"javascript": "javascriptreact",
// xml类型文件默认都是单引号,开启对非单引号的emmet识别
"xml": {
"attr_quotes": "single"
}
},
"emmet.includeLanguages": {
// 在react的jsx中添加对emmet的支持
"jsx-sublime-babel-tags": "javascriptreact"
},
//===========================================
//============= files =======================
//===========================================
// "files.autoSave": "onWindowChange", // 窗口失去焦点自动保存
// "files.autoSaveDelay": 1000, // 自动保存时间
"files.trimTrailingWhitespace": true, // 启用后,将在保存文件时剪裁尾随空格。
// 文件末尾插入新行
"files.trimTrailingWhitespace": true,
"files.insertFinalNewline": true,
// 删除文件末尾多余的新行
"files.trimFinalNewlines": true,
"files.eol": "\n",
"search.exclude": {
// 搜索排除这些区域
"**/node_modules": true,
"**/*.log": true,
"**/*.log*": true,
......@@ -76,8 +67,6 @@
"**/tmp": true
},
"files.exclude": {
// 排除文件搜索区域,比如node_modules(默认设置已经屏蔽了)
// "**/node_modules": true,
"**/bower_components": true,
"**/.idea": true,
"**/yarn.lock": true,
......@@ -100,7 +89,6 @@
"**/yarn.lock": true
},
"files.associations": {
// 配置文件关联,以便启用对应的智能提示,比如wxss使用css
"*.vue": "vue",
"*.wxss": "css"
},
......@@ -109,13 +97,11 @@
"css.validate": true,
"less.validate": true,
"scss.validate": true,
// ↓↓↓↓↓↓↓↓↓↓↓↓↓ 以下为插件设置 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
// ↓↓↓↓↓↓↓↓↓↓↓↓↓ 需要安装对应的插件 ↓↓↓↓↓↓↓↓↓↓↓↓
// ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
// ===========================================
// ================ Eslint ===================
// ===========================================
"eslint.enable": true, // 是否开启eslint
"eslint.enable": true,
"eslint.options": {
// 配置
"plugins": [
......@@ -126,53 +112,41 @@
"typescript"
]
},
"eslint.autoFixOnSave": true, // 保存自动格式化
"eslint.autoFixOnSave": true,
// ===========================================
// ================ Vetur ====================
// ===========================================
"vetur.experimental.templateInterpolationService": true,
"vetur.format.options.tabSize": 2,
"vetur.format.defaultFormatter.html": "js-beautify-html", // 使用js-beautify-html格式化
"vetur.format.defaultFormatter.scss": "prettier", // 使用js-beautify-html格式化
"vetur.format.defaultFormatter.css": "prettier", // 使用js-beautify-html格式化
// "vetur.format.defaultFormatter.html": "prettyhtml",
"vetur.format.defaultFormatter.html": "js-beautify-html",
"vetur.format.defaultFormatter.scss": "prettier",
"vetur.format.defaultFormatter.css": "prettier",
"vetur.format.defaultFormatter.ts": "prettier-tslint",
"vetur.format.defaultFormatter.js": "prettier",
"vetur.languageFeatures.codeActions": false,
// "vetur.useWorkspaceDependencies": true,
"vetur.languageFeatures.codeActions": false,
"vetur.format.defaultFormatterOptions": {
"js-beautify-html": {
// "wrap_attributes": "force-aligned", // 单行
"wrap_attributes": "force-expand-multiline" // 属性强制折行对齐 多行
"wrap_attributes": "force-expand-multiline"
},
"prettier": {
"eslintIntegration": true, // 让perttier使用eslint的格式进行检查
"arrowParens": "always", // 箭头函数参数括号 默认avoid 可选 avoid | always
"semi": false, // 使用分号, 默认true
"singleQuote": true // 使用单引号, 默认false(在jsx中配置无效, 默认都是双引号)
"eslintIntegration": true,
"arrowParens": "always",
"semi": false,
"singleQuote": true
}
},
// 函数注释
//===========================================
//============= Code Runner =================
//===========================================
"javascript.updateImportsOnFileMove.enabled": "never",
"liveServer.settings.donotShowInfoMsg": true,
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"terminal.integrated.rendererType": "dom", //关闭liveserver提示
"terminal.integrated.rendererType": "dom",
"telemetry.enableCrashReporter": false,
"telemetry.enableTelemetry": false,
"workbench.settings.enableNaturalLanguageSearch": false,
// 引用路径设置
"path-intellisense.mappings": {
"/@/": "${workspaceRoot}/src"
},
"prettier.requireConfig": true,
"typescript.updateImportsOnFileMove.enabled": "always",
"workbench.sideBar.location": "left",
"[javascriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
......@@ -203,8 +177,18 @@
"[markdown]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
}
}
},
"i18n-ally.localesPaths": [
"src/locales/lang",
],
"i18n-ally.keystyle": "nested",
"i18n-ally.sortKeys": true,
"i18n-ally.namespace": true,
"i18n-ally.pathMatcher":"{locale}/{namespaces}.{ext}",
"i18n-ally.enabledParsers": [
"ts"
],
"i18n-ally.sourceLanguage": "zh"
}
\ No newline at end of file
......@@ -3,6 +3,7 @@
### ✨ Features
- 还原 antdv 默认 loading,重构 `Loading` 组件,增加`useLoading``v-loading`指令。并增加示例
- i18n 支持 vscode `i18n-ally`插件
### 🎫 Chores
......
......@@ -29,7 +29,7 @@ export default defineComponent({
const visibleRef = ref(false);
const propsRef = ref<Partial<Nullable<DrawerProps>>>(null);
const { t } = useI18n('component.drawer');
const { t } = useI18n();
const getMergeProps = computed(
(): DrawerProps => {
......@@ -228,7 +228,11 @@ export default defineComponent({
default: () => (
<>
<div ref={scrollRef} style={unref(getScrollContentStyle)}>
<Loading absolute tip={t('loadingText')} loading={unref(getLoading)} />
<Loading
absolute
tip={t('component.drawer.loadingText')}
loading={unref(getLoading)}
/>
{getSlot(slots)}
</div>
{renderFooter()}
......
......@@ -2,7 +2,7 @@ import type { PropType } from 'vue';
import { useI18n } from '/@/hooks/web/useI18n';
import { propTypes } from '/@/utils/propTypes';
const { t } = useI18n('component.drawer');
const { t } = useI18n();
export const footerProps = {
confirmLoading: propTypes.bool,
......@@ -11,13 +11,13 @@ export const footerProps = {
*/
showCancelBtn: propTypes.bool.def(true),
cancelButtonProps: Object as PropType<any>,
cancelText: propTypes.string.def(t('cancelText')),
cancelText: propTypes.string.def(t('component.drawer.cancelText')),
/**
* @description: Show confirmation button
*/
showOkBtn: propTypes.bool.def(true),
okButtonProps: propTypes.any,
okText: propTypes.string.def(t('okText')),
okText: propTypes.string.def(t('component.drawer.okText')),
okType: propTypes.string.def('primary'),
showFooter: propTypes.bool,
footerHeight: {
......
<template>
<BasicModal
v-bind="$attrs"
:title="t('exportModalTitle')"
:title="t('component.excel.exportModalTitle')"
@ok="handleOk"
@register="registerModal"
>
......@@ -21,19 +21,19 @@
import { useI18n } from '/@/hooks/web/useI18n';
const { t } = useI18n('component.excel');
const { t } = useI18n();
const schemas: FormSchema[] = [
{
field: 'filename',
component: 'Input',
label: t('fileName'),
label: t('component.excel.fileName'),
rules: [{ required: true }],
},
{
field: 'bookType',
component: 'Select',
label: t('fileType'),
label: t('component.excel.fileType'),
defaultValue: 'xlsx',
rules: [{ required: true }],
componentProps: {
......
......@@ -9,7 +9,7 @@ import { getSlot } from '/@/utils/helper/tsxHelper';
import { useI18n } from '/@/hooks/web/useI18n';
import { propTypes } from '/@/utils/propTypes';
const { t } = useI18n('component.form');
const { t } = useI18n();
export default defineComponent({
name: 'BasicFormAction',
......@@ -38,14 +38,14 @@ export default defineComponent({
setup(props, { slots, emit }) {
const getResetBtnOptionsRef = computed(() => {
return {
text: t('resetButton'),
text: t('component.form.resetButton'),
...props.resetButtonOptions,
};
});
const getSubmitBtnOptionsRef = computed(() => {
return {
text: t('submitButton'),
text: t('component.form.submitButton'),
// htmlType: 'submit',
...props.submitButtonOptions,
};
......@@ -77,7 +77,7 @@ export default defineComponent({
<Button type="default" class="mr-2" onClick={toggleAdvanced}>
{() => (
<>
{isAdvanced ? t('putAway') : t('unfold')}
{isAdvanced ? t('component.form.putAway') : t('component.form.unfold')}
<BasicArrow expand={!isAdvanced} top />
</>
)}
......
......@@ -47,7 +47,7 @@ export default defineComponent({
},
},
setup(props, { slots }) {
const { t } = useI18n('component.form');
const { t } = useI18n();
// @ts-ignore
const itemLabelWidthRef = useItemLabelWidth(toRef(props, 'schema'), toRef(props, 'formProps'));
......@@ -175,7 +175,7 @@ export default defineComponent({
const characterInx = rules.findIndex((val) => val.max);
if (characterInx !== -1 && !rules[characterInx].validator) {
rules[characterInx].message =
rules[characterInx].message || t('maxTip', [rules[characterInx].max]);
rules[characterInx].message || t('component.form.maxTip', [rules[characterInx].max]);
}
return rules;
}
......
import type { ComponentType } from './types/index';
import { useI18n } from '/@/hooks/web/useI18n';
const { t } = useI18n('component.form');
const { t } = useI18n();
/**
* @description: 生成placeholder
*/
export function createPlaceholderMessage(component: ComponentType) {
if (component.includes('Input') || component.includes('Complete')) {
return t('input');
return t('component.form.input');
}
if (component.includes('Picker')) {
return t('choose');
return t('component.form.choose');
}
if (
component.includes('Select') ||
......@@ -21,7 +21,7 @@ export function createPlaceholderMessage(component: ComponentType) {
component.includes('Switch')
) {
// return `请选择${label}`;
return t('choose');
return t('component.form.choose');
}
return '';
}
......
<template>
<section class="menu-search-input" @Click="handleClick" :class="searchClass">
<a-input-search
:placeholder="t('search')"
:placeholder="t('component.menu.search')"
class="menu-search-input__search"
allowClear
@change="handleChange"
......@@ -29,7 +29,7 @@
},
},
setup(props, { emit }) {
const { t } = useI18n('component.menu');
const { t } = useI18n();
const [debounceEmitChange] = useDebounce(emitChange, 200);
......
......@@ -3,15 +3,15 @@ import { ButtonProps } from 'ant-design-vue/es/button/buttonTypes';
import { useI18n } from '/@/hooks/web/useI18n';
import { propTypes } from '/@/utils/propTypes';
const { t } = useI18n('component.modal');
const { t } = useI18n();
export const modalProps = {
visible: propTypes.bool,
// open drag
draggable: propTypes.bool.def(true),
centered: propTypes.bool,
cancelText: propTypes.string.def(t('cancelText')),
okText: propTypes.string.def(t('okText')),
cancelText: propTypes.string.def(t('component.modal.cancelText')),
okText: propTypes.string.def(t('component.modal.okText')),
closeFunc: Function as PropType<() => Promise<boolean>>,
};
......
......@@ -4,27 +4,27 @@
<Tooltip placement="top" v-if="getSetting.redo">
<template #title>
<span>{{ t('settingRedo') }}</span>
<span>{{ t('component.table.settingRedo') }}</span>
</template>
<RedoOutlined @click="redo" />
</Tooltip>
<Tooltip placement="top" v-if="getSetting.size">
<template #title>
<span>{{ t('settingDens') }}</span>
<span>{{ t('component.table.settingDens') }}</span>
</template>
<Dropdown placement="bottomCenter" :trigger="['click']">
<ColumnHeightOutlined />
<template #overlay>
<Menu @click="handleTitleClick" selectable v-model:selectedKeys="selectedKeysRef">
<MenuItem key="default">
<span>{{ t('settingDensDefault') }}</span>
<span>{{ t('component.table.settingDensDefault') }}</span>
</MenuItem>
<MenuItem key="middle">
<span>{{ t('settingDensMiddle') }}</span>
<span>{{ t('component.table.settingDensMiddle') }}</span>
</MenuItem>
<MenuItem key="small">
<span>{{ t('settingDensSmall') }}</span>
<span>{{ t('component.table.settingDensSmall') }}</span>
</MenuItem>
</Menu>
</template>
......@@ -140,7 +140,7 @@
defaultCheckList: [],
});
const { t } = useI18n('component.table');
const { t } = useI18n();
watchEffect(() => {
const columns = table.getColumns();
......
......@@ -6,7 +6,7 @@ import { PAGE_SIZE } from '../const';
import { useProps } from './useProps';
import { useI18n } from '/@/hooks/web/useI18n';
const { t } = useI18n('component.table');
const { t } = useI18n();
export function useColumns(
refProps: ComputedRef<BasicTableProps>,
getPaginationRef: ComputedRef<false | PaginationProps>
......@@ -44,7 +44,7 @@ export function useColumns(
columns.unshift({
flag: 'INDEX',
width: 50,
title: t('index'),
title: t('component.table.index'),
align: 'center',
customRender: ({ index }) => {
const getPagination = unref(getPaginationRef);
......
......@@ -10,7 +10,7 @@ import { PAGE_SIZE, PAGE_SIZE_OPTIONS } from '../const';
import { useProps } from './useProps';
import { useI18n } from '/@/hooks/web/useI18n';
const { t } = useI18n('component.table');
const { t } = useI18n();
export function usePagination(refProps: ComputedRef<BasicTableProps>) {
const configRef = ref<PaginationProps>({});
const { propsRef } = useProps(refProps);
......@@ -25,7 +25,7 @@ export function usePagination(refProps: ComputedRef<BasicTableProps>) {
pageSize: PAGE_SIZE,
size: 'small',
defaultPageSize: PAGE_SIZE,
showTotal: (total) => t('total', { total }),
showTotal: (total) => t('component.table.total', { total }),
showSizeChanger: true,
pageSizeOptions: PAGE_SIZE_OPTIONS,
itemRender: ({ page, type, originalElement }) => {
......
......@@ -2,11 +2,11 @@
<div>
<a-button-group>
<a-button type="primary" @click="openUploadModal" preIcon="ant-design:cloud-upload-outlined">
{{ t('upload') }}
{{ t('component.upload.upload') }}
</a-button>
<Tooltip placement="bottom" v-if="showPreview">
<template #title>
{{ t('uploaded') }}
{{ t('component.upload.uploaded') }}
<template v-if="fileListRef.length">{{ fileListRef.length }}</template>
</template>
<a-button @click="openPreviewModal">
......@@ -46,7 +46,7 @@
components: { UploadModal, UploadPreviewModal, Icon, Tooltip },
props: uploadContainerProps,
setup(props, { emit, attrs }) {
const { t } = useI18n('component.upload');
const { t } = useI18n();
// 上传modal
const [registerUploadModal, { openModal: openUploadModal }] = useModal();
......
<template>
<BasicModal
width="800px"
:title="t('upload')"
:okText="t('save')"
:title="t('component.upload.upload')"
:okText="t('component.upload.save')"
v-bind="$attrs"
@register="register"
@ok="handleOk"
......@@ -31,7 +31,7 @@
:before-upload="beforeUpload"
class="upload-modal-toolbar__btn"
>
<a-button type="primary"> {{ t('choose') }} </a-button>
<a-button type="primary"> {{ t('component.upload.choose') }} </a-button>
</Upload>
</div>
<FileList :dataSource="fileListRef" :columns="columns" :actionColumn="actionColumn" />
......@@ -64,7 +64,7 @@
props: basicProps,
setup(props, { emit }) {
// 是否正在上传
const { t } = useI18n('component.upload');
const { t } = useI18n();
const isUploadingRef = ref(false);
const fileListRef = ref<FileItem[]>([]);
......@@ -105,10 +105,10 @@
(item) => item.status === UploadResultStatus.ERROR
);
return isUploadingRef.value
? t('uploading')
? t('component.upload.uploading')
: someError
? t('reUploadFailed')
: t('startUpload');
? t('component.upload.reUploadFailed')
: t('component.upload.startUpload');
});
// 上传前校验
......@@ -119,13 +119,13 @@
// 设置最大值,则判断
if (maxSize && file.size / 1024 / 1024 >= maxSize) {
createMessage.error(t('maxSizeMultiple', [maxSize]));
createMessage.error(t('component.upload.maxSizeMultiple', [maxSize]));
return false;
}
// 设置类型,则判断
if (accept.length > 0 && !checkFileType(file, accept)) {
createMessage.error!(t('acceptUpload', [accept.join(',')]));
createMessage.error!(t('acomponent.upload.cceptUpload', [accept.join(',')]));
return false;
}
const commonItem = {
......@@ -206,7 +206,7 @@
async function handleStartUpload() {
const { maxNumber } = props;
if (fileListRef.value.length > maxNumber) {
return createMessage.warning(t('maxNumber', [maxNumber]));
return createMessage.warning(t('component.upload.maxNumber', [maxNumber]));
}
try {
isUploadingRef.value = true;
......@@ -233,10 +233,10 @@
const { maxNumber } = props;
if (fileListRef.value.length > maxNumber) {
return createMessage.warning(t('maxNumber', [maxNumber]));
return createMessage.warning(t('component.upload.maxNumber', [maxNumber]));
}
if (isUploadingRef.value) {
return createMessage.warning(t('saveWarn'));
return createMessage.warning(t('component.upload.saveWarn'));
}
const fileList: string[] = [];
......@@ -248,7 +248,7 @@
}
// 存在一个上传成功的即可保存
if (fileList.length <= 0) {
return createMessage.warning(t('saveError'));
return createMessage.warning(t('component.upload.saveError'));
}
fileListRef.value = [];
closeModal();
......@@ -261,7 +261,7 @@
fileListRef.value = [];
return true;
} else {
createMessage.warning(t('uploadWait'));
createMessage.warning(t('component.upload.uploadWait'));
return false;
}
}
......
<template>
<BasicModal
width="800px"
:title="t('preview')"
:title="t('component.upload.preview')"
wrapClassName="upload-preview-modal"
v-bind="$attrs"
@register="register"
......@@ -30,7 +30,7 @@
props: previewProps,
setup(props, { emit }) {
const [register, { closeModal }] = useModalInner();
const { t } = useI18n('component.upload');
const { t } = useI18n();
const fileListRef = ref<PreviewFileItem[]>([]);
watch(
......
......@@ -7,14 +7,14 @@ import { Progress, Tag } from 'ant-design-vue';
import TableAction from '/@/components/Table/src/components/TableAction';
import { useI18n } from '/@/hooks/web/useI18n';
const { t } = useI18n('component.upload');
const { t } = useI18n();
// 文件上传列表
export function createTableColumns(): BasicColumn[] {
return [
{
dataIndex: 'thumbUrl',
title: t('legend'),
title: t('component.upload.legend'),
width: 100,
customRender: ({ record }) => {
const { thumbUrl, type } = (record as FileItem) || {};
......@@ -23,7 +23,7 @@ export function createTableColumns(): BasicColumn[] {
},
{
dataIndex: 'name',
title: t('fileName'),
title: t('component.upload.fileName'),
align: 'left',
customRender: ({ text, record }) => {
const { percent, status: uploadStatus } = (record as FileItem) || {};
......@@ -47,7 +47,7 @@ export function createTableColumns(): BasicColumn[] {
},
{
dataIndex: 'size',
title: t('fileSize'),
title: t('component.upload.fileSize'),
width: 100,
customRender: ({ text = 0 }) => {
return text && (text / 1024).toFixed(2) + 'KB';
......@@ -60,15 +60,15 @@ export function createTableColumns(): BasicColumn[] {
// },
{
dataIndex: 'status',
title: t('fileStatue'),
title: t('component.upload.fileStatue'),
width: 100,
customRender: ({ text }) => {
if (text === UploadResultStatus.SUCCESS) {
return <Tag color="green">{() => t('uploadSuccess')}</Tag>;
return <Tag color="green">{() => t('component.upload.uploadSuccess')}</Tag>;
} else if (text === UploadResultStatus.ERROR) {
return <Tag color="red">{() => t('uploadError')}</Tag>;
return <Tag color="red">{() => t('component.upload.uploadError')}</Tag>;
} else if (text === UploadResultStatus.UPLOADING) {
return <Tag color="blue">{() => t('uploading')}</Tag>;
return <Tag color="blue">{() => t('component.upload.uploading')}</Tag>;
}
return text;
......@@ -79,20 +79,20 @@ export function createTableColumns(): BasicColumn[] {
export function createActionColumn(handleRemove: Function, handlePreview: Function): BasicColumn {
return {
width: 120,
title: t('operating'),
title: t('component.upload.operating'),
dataIndex: 'action',
fixed: false,
customRender: ({ record }) => {
const actions: ActionItem[] = [
{
label: t('del'),
label: t('component.upload.del'),
color: 'error',
onClick: handleRemove.bind(null, record),
},
];
if (checkImgType(record)) {
actions.unshift({
label: t('preview'),
label: t('component.upload.preview'),
onClick: handlePreview.bind(null, record),
});
}
......@@ -105,7 +105,7 @@ export function createPreviewColumns(): BasicColumn[] {
return [
{
dataIndex: 'url',
title: t('legend'),
title: t('component.upload.legend'),
width: 100,
customRender: ({ record }) => {
const { url, type } = (record as PreviewFileItem) || {};
......@@ -116,7 +116,7 @@ export function createPreviewColumns(): BasicColumn[] {
},
{
dataIndex: 'name',
title: t('fileName'),
title: t('component.upload.fileName'),
align: 'left',
},
];
......@@ -133,7 +133,7 @@ export function createPreviewActionColumn({
}): BasicColumn {
return {
width: 160,
title: t('operating'),
title: t('component.upload.operating'),
dataIndex: 'action',
fixed: false,
customRender: ({ record }) => {
......@@ -141,18 +141,18 @@ export function createPreviewActionColumn({
const actions: ActionItem[] = [
{
label: t('del'),
label: t('component.upload.del'),
color: 'error',
onClick: handleRemove.bind(null, record),
},
{
label: t('download'),
label: t('component.upload.download'),
onClick: handleDownload.bind(null, record),
},
];
if (isImgTypeByName(url)) {
actions.unshift({
label: t('preview'),
label: t('component.upload.preview'),
onClick: handlePreview.bind(null, record),
});
}
......
import { Ref, unref, computed } from 'vue';
import { useI18n } from '/@/hooks/web/useI18n';
const { t } = useI18n('component.upload');
const { t } = useI18n();
export function useUploadType({
acceptRef,
// uploadTypeRef,
......@@ -38,17 +38,17 @@ export function useUploadType({
const accept = unref(acceptRef);
if (accept.length > 0) {
helpTexts.push(t('accept', [accept.join(',')]));
helpTexts.push(t('component.upload.accept', [accept.join(',')]));
}
const maxSize = unref(maxSizeRef);
if (maxSize) {
helpTexts.push(t('maxSize', [maxSize]));
helpTexts.push(t('component.upload.maxSize', [maxSize]));
}
const maxNumber = unref(maxNumberRef);
if (maxNumber && maxNumber !== Infinity) {
helpTexts.push(t('maxNumber', [maxNumber]));
helpTexts.push(t('component.upload.maxNumber', [maxNumber]));
}
return helpTexts.join('');
});
......
......@@ -30,7 +30,7 @@ export default defineComponent({
endTime: 0,
draged: false,
});
const { t } = useI18n('component.verify');
const { t } = useI18n();
watch(
() => state.isPassing,
......@@ -146,7 +146,9 @@ export default defineComponent({
/>
{state.showTip && (
<span class={[`ir-dv-img__tip`, state.isPassing ? 'success' : 'error']}>
{state.isPassing ? t('time', { time: time.toFixed(1) }) : t('error')}
{state.isPassing
? t('component.verify.time', { time: time.toFixed(1) })
: t('component.verify.error')}
</span>
)}
{!state.showTip && !state.draged && (
......
import type { PropType } from 'vue';
import { useI18n } from '/@/hooks/web/useI18n';
const { t } = useI18n('component.verify');
const { t } = useI18n();
export const basicProps = {
value: {
type: Boolean as PropType<boolean>,
......@@ -15,11 +15,11 @@ export const basicProps = {
text: {
type: [String] as PropType<string>,
default: t('dragText'),
default: t('component.verify.dragText'),
},
successText: {
type: [String] as PropType<string>,
default: t('successText'),
default: t('component.verify.successText'),
},
height: {
type: [Number, String] as PropType<number | string>,
......
......@@ -13,16 +13,16 @@ import { useI18n } from '/@/hooks/web/useI18n';
export default defineComponent({
name: 'LayoutContent',
setup() {
const { t } = useI18n('layout.footer');
const { t } = useI18n();
return () => {
return (
<Layout.Footer class="layout-footer">
{() => (
<>
<div class="layout-footer__links">
<a onClick={() => openWindow(SITE_URL)}>{t('onlinePreview')}</a>
<a onClick={() => openWindow(SITE_URL)}>{t('layout.footer.onlinePreview')}</a>
<GithubFilled onClick={() => openWindow(GITHUB_URL)} class="github" />
<a onClick={() => openWindow(DOC_URL)}>{t('onlineDocument')}</a>
<a onClick={() => openWindow(DOC_URL)}>{t('layout.footer.onlineDocument')}</a>
</div>
<div>Copyright &copy;2020 Vben Admin</div>
</>
......
......@@ -66,7 +66,7 @@ export default defineComponent({
const logoWidthRef = ref(200);
const logoRef = ref<ComponentRef>(null);
const { refreshPage } = useTabs();
const { t } = useI18n('layout.header');
const { t } = useI18n();
const { getShowTopMenu, getShowHeaderTrigger, getSplit, getTopMenuAlign } = useMenuSetting();
......
......@@ -44,7 +44,7 @@ const MenuItem: FunctionalComponent<MenuItemProps> = (props) => {
export default defineComponent({
name: 'UserDropdown',
setup() {
const { t } = useI18n('layout.header');
const { t } = useI18n();
const { getShowDoc } = useHeaderSetting();
const getUserInfo = computed(() => {
......@@ -91,12 +91,18 @@ export default defineComponent({
<Menu onClick={handleMenuClick}>
{() => (
<>
{showDoc && <MenuItem key="doc" text={t('dropdownItemDoc')} icon="gg:loadbar-doc" />}
{showDoc && (
<MenuItem
key="doc"
text={t('layout.header.dropdownItemDoc')}
icon="gg:loadbar-doc"
/>
)}
{/* @ts-ignore */}
{showDoc && <Menu.Divider />}
<MenuItem
key="loginOut"
text={t('dropdownItemLoginOut')}
text={t('layout.header.dropdownItemLoginOut')}
icon="ant-design:poweroff-outlined"
/>
</>
......
......@@ -15,7 +15,7 @@ const prefixCls = 'lock-modal';
export default defineComponent({
name: 'LockModal',
setup(_, { attrs }) {
const { t } = useI18n('layout.header');
const { t } = useI18n();
const [register, { closeModal }] = useModalInner();
const [registerForm, { validateFields, resetFields }] = useForm({
......@@ -23,7 +23,7 @@ export default defineComponent({
schemas: [
{
field: 'password',
label: t('lockScreenPassword'),
label: t('layout.header.lockScreenPassword'),
component: 'InputPassword',
required: true,
},
......@@ -53,7 +53,7 @@ export default defineComponent({
return () => (
<BasicModal
footer={null}
title={t('lockScreen')}
title={t('layout.header.lockScreen')}
{...attrs}
class={prefixCls}
onRegister={register}
......@@ -69,10 +69,10 @@ export default defineComponent({
<div class={`${prefixCls}__footer`}>
<Button type="primary" block class="mt-2" onClick={lock}>
{() => t('lockScreenBtn')}
{() => t('layout.header.lockScreenBtn')}
</Button>
<Button block class="mt-2" onClick={lock.bind(null, false)}>
{() => t('notLockScreenPassword')}
{() => t('layout.header.notLockScreenPassword')}
</Button>
</div>
</div>
......
......@@ -59,7 +59,7 @@ export default defineComponent({
},
},
setup(props) {
const { t } = useI18n('layout.multipleTab');
const { t } = useI18n();
const { getShowMenu } = useMenuSetting();
const { getShowHeader } = useHeaderSetting();
const { getShowQuick } = useMultipleTabSetting();
......@@ -76,7 +76,7 @@ export default defineComponent({
return () => {
const scaleAction = getScaleAction(
unref(getIsScale) ? t('putAway') : t('unfold'),
unref(getIsScale) ? t('layout.multipleTab.putAway') : t('layout.multipleTab.unfold'),
unref(getIsScale)
);
const dropMenuList = unref(getDropMenuList) || [];
......
......@@ -4,7 +4,7 @@ import type { TabItem } from '/@/store/modules/tab';
import { useI18n } from '/@/hooks/web/useI18n';
const { t } = useI18n('layout.multipleTab');
const { t } = useI18n();
export enum TabContentEnum {
TAB_TYPE,
......@@ -41,40 +41,40 @@ export function getActions() {
const REFRESH_PAGE: DropMenu = {
icon: 'ant-design:reload-outlined',
event: MenuEventEnum.REFRESH_PAGE,
text: t('redo'),
text: t('layout.multipleTab.redo'),
disabled: false,
};
const CLOSE_CURRENT: DropMenu = {
icon: 'ant-design:close-outlined',
event: MenuEventEnum.CLOSE_CURRENT,
text: t('close'),
text: t('layout.multipleTab.close'),
disabled: false,
divider: true,
};
const CLOSE_LEFT: DropMenu = {
icon: 'ant-design:pic-left-outlined',
event: MenuEventEnum.CLOSE_LEFT,
text: t('closeLeft'),
text: t('layout.multipleTab.closeLeft'),
disabled: false,
divider: false,
};
const CLOSE_RIGHT: DropMenu = {
icon: 'ant-design:pic-right-outlined',
event: MenuEventEnum.CLOSE_RIGHT,
text: t('closeRight'),
text: t('layout.multipleTab.closeRight'),
disabled: false,
divider: true,
};
const CLOSE_OTHER: DropMenu = {
icon: 'ant-design:pic-center-outlined',
event: MenuEventEnum.CLOSE_OTHER,
text: t('closeOther'),
text: t('layout.multipleTab.closeOther'),
disabled: false,
};
const CLOSE_ALL: DropMenu = {
icon: 'ant-design:line-outlined',
event: MenuEventEnum.CLOSE_ALL,
text: t('closeAll'),
text: t('layout.multipleTab.closeAll'),
disabled: false,
};
return [REFRESH_PAGE, CLOSE_CURRENT, CLOSE_LEFT, CLOSE_RIGHT, CLOSE_OTHER, CLOSE_ALL];
......
......@@ -56,7 +56,7 @@ interface ThemePickerProps {
}
const { createSuccessModal, createMessage } = useMessage();
const { t } = useI18n('layout.setting');
const { t } = useI18n();
/**
* Menu type Picker comp
......@@ -122,8 +122,8 @@ const FooterButton: FunctionalComponent = () => {
const { isSuccessRef } = useCopyToClipboard(JSON.stringify(unref(getRootSetting), null, 2));
unref(isSuccessRef) &&
createSuccessModal({
title: t('operatingTitle'),
content: t('operatingContent'),
title: t('layout.setting.operatingTitle'),
content: t('layout.setting.operatingContent'),
});
}
function handleResetSetting() {
......@@ -133,7 +133,7 @@ const FooterButton: FunctionalComponent = () => {
// updateTheme(themeColor);
updateColorWeak(colorWeak);
updateGrayMode(grayMode);
createMessage.success(t('resetSuccess'));
createMessage.success(t('layout.setting.resetSuccess'));
} catch (error) {
createMessage.error(error);
}
......@@ -151,7 +151,7 @@ const FooterButton: FunctionalComponent = () => {
{() => (
<>
<CopyOutlined class="mr-2" />
{t('copyBtn')}
{t('layout.setting.copyBtn')}
</>
)}
</Button>
......@@ -159,7 +159,7 @@ const FooterButton: FunctionalComponent = () => {
{() => (
<>
<RedoOutlined class="mr-2" />
{t('resetBtn')}
{t('layout.setting.resetBtn')}
</>
)}
</Button>
......@@ -167,7 +167,7 @@ const FooterButton: FunctionalComponent = () => {
{() => (
<>
<RedoOutlined class="mr-2" />
{t('clearBtn')}
{t('layout.setting.clearBtn')}
</>
)}
</Button>
......@@ -226,7 +226,7 @@ export default defineComponent({
return (
<>
<MenuTypePicker />
{renderSwitchItem(t('splitMenu'), {
{renderSwitchItem(t('layout.setting.splitMenu'), {
handler: (e) => {
baseHandler(HandlerEnum.MENU_SPLIT, e);
},
......@@ -240,7 +240,7 @@ export default defineComponent({
function renderTheme() {
return (
<>
<Divider>{() => t('headerTheme')}</Divider>
<Divider>{() => t('layout.setting.headerTheme')}</Divider>
<ThemePicker
colorList={HEADER_PRESET_BG_COLOR_LIST}
def={unref(getHeaderBgColor)}
......@@ -248,7 +248,7 @@ export default defineComponent({
baseHandler(HandlerEnum.HEADER_THEME, e);
}}
/>
<Divider>{() => t('sidebarTheme')}</Divider>
<Divider>{() => t('layout.setting.sidebarTheme')}</Divider>
<ThemePicker
colorList={SIDE_BAR_BG_COLOR_LIST}
def={unref(getMenuBgColor)}
......@@ -265,56 +265,56 @@ export default defineComponent({
*/
function renderFeatures() {
return [
renderSwitchItem(t('menuDrag'), {
renderSwitchItem(t('layout.setting.menuDrag'), {
handler: (e) => {
baseHandler(HandlerEnum.MENU_HAS_DRAG, e);
},
def: unref(getCanDrag),
disabled: !unref(getShowMenuRef),
}),
renderSwitchItem(t('menuSearch'), {
renderSwitchItem(t('layout.setting.menuSearch'), {
handler: (e) => {
baseHandler(HandlerEnum.MENU_SHOW_SEARCH, e);
},
def: unref(getShowSearch),
disabled: !unref(getShowMenuRef),
}),
renderSwitchItem(t('menuAccordion'), {
renderSwitchItem(t('layout.setting.menuAccordion'), {
handler: (e) => {
baseHandler(HandlerEnum.MENU_ACCORDION, e);
},
def: unref(getAccordion),
disabled: !unref(getShowMenuRef),
}),
renderSwitchItem(t('menuCollapse'), {
renderSwitchItem(t('layout.setting.menuCollapse'), {
handler: (e) => {
baseHandler(HandlerEnum.MENU_COLLAPSED, e);
},
def: unref(getCollapsed),
disabled: !unref(getShowMenuRef),
}),
renderSwitchItem(t('collapseMenuDisplayName'), {
renderSwitchItem(t('layout.setting.collapseMenuDisplayName'), {
handler: (e) => {
baseHandler(HandlerEnum.MENU_COLLAPSED_SHOW_TITLE, e);
},
def: unref(getCollapsedShowTitle),
disabled: !unref(getShowMenuRef) || !unref(getCollapsed),
}),
renderSwitchItem(t('fixedHeader'), {
renderSwitchItem(t('layout.setting.fixedHeader'), {
handler: (e) => {
baseHandler(HandlerEnum.HEADER_FIXED, e);
},
def: unref(getHeaderFixed),
disabled: !unref(getShowHeader),
}),
renderSwitchItem(t('fixedSideBar'), {
renderSwitchItem(t('layout.setting.fixedSideBar'), {
handler: (e) => {
baseHandler(HandlerEnum.MENU_FIXED, e);
},
def: unref(getMenuFixed),
disabled: !unref(getShowMenuRef),
}),
renderSelectItem(t('topMenuLayout'), {
renderSelectItem(t('layout.setting.topMenuLayout'), {
handler: (e) => {
baseHandler(HandlerEnum.MENU_TOP_ALIGN, e);
},
......@@ -322,7 +322,7 @@ export default defineComponent({
options: topMenuAlignOptions,
disabled: !unref(getShowHeader) || (!unref(getIsTopMenu) && !unref(getSplit)),
}),
renderSelectItem(t('menuCollapseButton'), {
renderSelectItem(t('layout.setting.menuCollapseButton'), {
handler: (e) => {
baseHandler(HandlerEnum.MENU_TRIGGER, e);
},
......@@ -331,7 +331,7 @@ export default defineComponent({
options: menuTriggerOptions,
}),
renderSelectItem(t('contentMode'), {
renderSelectItem(t('layout.setting.contentMode'), {
handler: (e) => {
baseHandler(HandlerEnum.CONTENT_MODE, e);
},
......@@ -339,7 +339,7 @@ export default defineComponent({
options: contentModeOptions,
}),
<div class={`setting-drawer__cell-item`}>
<span>{t('autoScreenLock')}</span>
<span>{t('layout.setting.autoScreenLock')}</span>
<InputNumber
style="width:126px"
size="small"
......@@ -350,14 +350,14 @@ export default defineComponent({
defaultValue={appStore.getProjectConfig.lockTime}
formatter={(value: string) => {
if (parseInt(value) === 0) {
return `0(${t('notAutoScreenLock')})`;
return `0(${t('layout.setting.notAutoScreenLock')})`;
}
return `${value}${t('minute')}`;
return `${value}${t('layout.setting.minute')}`;
}}
/>
</div>,
<div class={`setting-drawer__cell-item`}>
<span>{t('expandedMenuWidth')}</span>
<span>{t('layout.setting.expandedMenuWidth')}</span>
<InputNumber
style="width:126px"
size="small"
......@@ -377,27 +377,27 @@ export default defineComponent({
function renderContent() {
return [
renderSwitchItem(t('breadcrumb'), {
renderSwitchItem(t('layout.setting.breadcrumb'), {
handler: (e) => {
baseHandler(HandlerEnum.SHOW_BREADCRUMB, e);
},
def: unref(getShowBreadCrumb),
disabled: !unref(getShowHeader),
}),
renderSwitchItem(t('breadcrumbIcon'), {
renderSwitchItem(t('layout.setting.breadcrumbIcon'), {
handler: (e) => {
baseHandler(HandlerEnum.SHOW_BREADCRUMB_ICON, e);
},
def: unref(getShowBreadCrumbIcon),
disabled: !unref(getShowHeader),
}),
renderSwitchItem(t('tabs'), {
renderSwitchItem(t('layout.setting.tabs'), {
handler: (e) => {
baseHandler(HandlerEnum.TABS_SHOW, e);
},
def: unref(getShowMultipleTab),
}),
renderSwitchItem(t('tabsQuickBtn'), {
renderSwitchItem(t('layout.setting.tabsQuickBtn'), {
handler: (e) => {
baseHandler(HandlerEnum.TABS_SHOW_QUICK, e);
},
......@@ -405,14 +405,14 @@ export default defineComponent({
disabled: !unref(getShowMultipleTab),
}),
renderSwitchItem(t('sidebar'), {
renderSwitchItem(t('layout.setting.sidebar'), {
handler: (e) => {
baseHandler(HandlerEnum.MENU_SHOW_SIDEBAR, e);
},
def: unref(getShowMenu),
disabled: unref(getIsHorizontal),
}),
renderSwitchItem(t('header'), {
renderSwitchItem(t('layout.setting.header'), {
handler: (e) => {
baseHandler(HandlerEnum.HEADER_SHOW, e);
},
......@@ -424,25 +424,25 @@ export default defineComponent({
},
def: unref(getShowLogo),
}),
renderSwitchItem(t('footer'), {
renderSwitchItem(t('layout.setting.footer'), {
handler: (e) => {
baseHandler(HandlerEnum.SHOW_FOOTER, e);
},
def: unref(getShowFooter),
}),
renderSwitchItem(t('fullContent'), {
renderSwitchItem(t('layout.setting.fullContent'), {
handler: (e) => {
baseHandler(HandlerEnum.FULL_CONTENT, e);
},
def: unref(getFullContent),
}),
renderSwitchItem(t('grayMode'), {
renderSwitchItem(t('layout.setting.grayMode'), {
handler: (e) => {
baseHandler(HandlerEnum.GRAY_MODE, e);
},
def: unref(getGrayMode),
}),
renderSwitchItem(t('colorWeak'), {
renderSwitchItem(t('layout.setting.colorWeak'), {
handler: (e) => {
baseHandler(HandlerEnum.COLOR_WEAK, e);
},
......@@ -454,13 +454,13 @@ export default defineComponent({
function renderTransition() {
return (
<>
{renderSwitchItem(t('progress'), {
{renderSwitchItem(t('layout.setting.progress'), {
handler: (e) => {
baseHandler(HandlerEnum.OPEN_PROGRESS, e);
},
def: unref(getOpenNProgress),
})}
{renderSwitchItem(t('switchLoading'), {
{renderSwitchItem(t('layout.setting.switchLoading'), {
handler: (e) => {
baseHandler(HandlerEnum.OPEN_PAGE_LOADING, e);
},
......@@ -468,14 +468,14 @@ export default defineComponent({
disabled: !unref(getEnableTransition),
})}
{renderSwitchItem(t('switchAnimation'), {
{renderSwitchItem(t('layout.setting.switchAnimation'), {
handler: (e) => {
baseHandler(HandlerEnum.OPEN_ROUTE_TRANSITION, e);
},
def: unref(getEnableTransition),
})}
{renderSelectItem(t('animationType'), {
{renderSelectItem(t('layout.setting.animationType'), {
handler: (e) => {
baseHandler(HandlerEnum.ROUTER_TRANSITION, e);
},
......@@ -519,26 +519,31 @@ export default defineComponent({
onChange={(e: any) => {
handler && handler(e);
}}
checkedChildren={t('on')}
unCheckedChildren={t('off')}
checkedChildren={t('layout.setting.on')}
unCheckedChildren={t('layout.setting.off')}
/>
</div>
);
}
return () => (
<BasicDrawer {...attrs} title={t('drawerTitle')} width={330} wrapClassName="setting-drawer">
<BasicDrawer
{...attrs}
title={t('layout.setting.drawerTitle')}
width={330}
wrapClassName="setting-drawer"
>
{{
default: () => (
<>
<Divider>{() => t('navMode')}</Divider>
<Divider>{() => t('layout.setting.navMode')}</Divider>
{renderSidebar()}
{renderTheme()}
<Divider>{() => t('interfaceFunction')}</Divider>
<Divider>{() => t('layout.setting.interfaceFunction')}</Divider>
{renderFeatures()}
<Divider>{() => t('interfaceDisplay')}</Divider>
<Divider>{() => t('layout.setting.interfaceDisplay')}</Divider>
{renderContent()}
<Divider>{() => t('animation')}</Divider>
<Divider>{() => t('layout.setting.animation')}</Divider>
{renderTransition()}
<Divider />
<FooterButton />
......
......@@ -6,7 +6,7 @@ import sidebarImg from '/@/assets/images/layout/menu-sidebar.svg';
import menuTopImg from '/@/assets/images/layout/menu-top.svg';
import { useI18n } from '/@/hooks/web/useI18n';
const { t } = useI18n('layout.setting');
const { t } = useI18n();
export enum HandlerEnum {
CHANGE_LAYOUT,
......@@ -51,41 +51,41 @@ export enum HandlerEnum {
export const contentModeOptions = [
{
value: ContentEnum.FULL,
label: t('contentModeFull'),
label: t('layout.setting.contentModeFull'),
},
{
value: ContentEnum.FIXED,
label: t('contentModeFixed'),
label: t('layout.setting.contentModeFixed'),
},
];
export const topMenuAlignOptions = [
{
value: TopMenuAlignEnum.CENTER,
label: t('topMenuAlignRight'),
label: t('layout.setting.topMenuAlignRight'),
},
{
value: TopMenuAlignEnum.START,
label: t('topMenuAlignLeft'),
label: t('layout.setting.topMenuAlignLeft'),
},
{
value: TopMenuAlignEnum.END,
label: t('topMenuAlignCenter'),
label: t('layout.setting.topMenuAlignCenter'),
},
];
export const menuTriggerOptions = [
{
value: TriggerEnum.NONE,
label: t('menuTriggerNone'),
label: t('layout.setting.menuTriggerNone'),
},
{
value: TriggerEnum.FOOTER,
label: t('menuTriggerBottom'),
label: t('layout.setting.menuTriggerBottom'),
},
{
value: TriggerEnum.HEADER,
label: t('menuTriggerTop'),
label: t('layout.setting.menuTriggerTop'),
},
];
......@@ -104,20 +104,20 @@ export const routerTransitionOptions = [
export const menuTypeList = [
{
title: t('menuTypeSidebar'),
title: t('layout.setting.menuTypeSidebar'),
mode: MenuModeEnum.INLINE,
type: MenuTypeEnum.SIDEBAR,
src: sidebarImg,
},
{
title: t('menuTypeMix'),
title: t('layout.setting.menuTypeMix'),
mode: MenuModeEnum.INLINE,
type: MenuTypeEnum.MIX,
src: mixImg,
},
{
title: t('menuTypeTopMenu'),
title: t('layout.setting.menuTypeTopMenu'),
mode: MenuModeEnum.HORIZONTAL,
type: MenuTypeEnum.TOP_MENU,
src: menuTopImg,
......
......@@ -22,7 +22,7 @@ import { useMessage } from '/@/hooks/web/useMessage';
// import { warn } from '/@/utils/log';
import { useI18n } from '/@/hooks/web/useI18n';
const { t } = useI18n('sys.app');
const { t } = useI18n();
const { createMessage } = useMessage();
const NAME = 'permission';
......@@ -104,7 +104,7 @@ class Permission extends VuexModule {
} else if (permissionMode === PermissionModeEnum.BACK) {
const messageKey = 'loadMenu';
createMessage.loading({
content: t('menuLoading'),
content: t('sys.app.menuLoading'),
key: messageKey,
duration: 1,
});
......
......@@ -143,11 +143,11 @@ class User extends VuexModule {
@Action
async confirmLoginOut() {
const { createConfirm } = useMessage();
const { t } = useI18n('sys.app');
const { t } = useI18n();
createConfirm({
iconType: 'warning',
title: t('loginOutTip'),
content: t('loginOutMessage'),
title: t('sys.app.loginOutTip'),
content: t('sys.app.loginOutMessage'),
onOk: async () => {
await this.loginOut(true);
},
......
......@@ -5,7 +5,7 @@ const { createMessage } = useMessage();
const error = createMessage.error!;
export function checkStatus(status: number, msg: string): void {
const { t } = useI18n('sys.api');
const { t } = useI18n();
switch (status) {
case 400:
error(`${msg}`);
......@@ -14,39 +14,39 @@ export function checkStatus(status: number, msg: string): void {
// 未登录则跳转登录页面,并携带当前页面的路径
// 在登录成功后返回当前页面,这一步需要在登录页操作。
case 401:
error(t('errMsg401'));
error(t('sys.api.errMsg401'));
userStore.loginOut(true);
break;
case 403:
error(t('errMsg403'));
error(t('sys.api.errMsg403'));
break;
// 404请求不存在
case 404:
error(t('errMsg404'));
error(t('sys.api.errMsg404'));
break;
case 405:
error(t('errMsg405'));
error(t('sys.api.errMsg405'));
break;
case 408:
error(t('errMsg408'));
error(t('sys.api.errMsg408'));
break;
case 500:
error(t('errMsg500'));
error(t('sys.api.errMsg500'));
break;
case 501:
error(t('errMsg501'));
error(t('sys.api.errMsg501'));
break;
case 502:
error(t('errMsg502'));
error(t('sys.api.errMsg502'));
break;
case 503:
error(t('errMsg503'));
error(t('sys.api.errMsg503'));
break;
case 504:
error(t('errMsg504'));
error(t('sys.api.errMsg504'));
break;
case 505:
error(t('errMsg505'));
error(t('sys.api.errMsg505'));
break;
default:
}
......
......@@ -34,7 +34,7 @@ const transform: AxiosTransform = {
* @description: 处理请求数据
*/
transformRequestData: (res: AxiosResponse<Result>, options: RequestOptions) => {
const { t } = useI18n('sys.api');
const { t } = useI18n();
const { isTransformRequestResult } = options;
// 不进行任何处理,直接返回
// 用于页面代码可能需要直接获取code,data,message这些信息时开启
......@@ -57,7 +57,7 @@ const transform: AxiosTransform = {
if (message) {
// errorMessageMode=‘modal’的时候会显示modal错误弹窗,而不是消息提示,用于一些比较重要的错误
if (options.errorMessageMode === 'modal') {
createErrorModal({ title: t('errorTip'), content: message });
createErrorModal({ title: t('sys.api.errorTip'), content: message });
} else {
createMessage.error(message);
}
......@@ -76,7 +76,7 @@ const transform: AxiosTransform = {
createMessage.error(data.message);
Promise.reject(new Error(message));
} else {
const msg = t('errorMessage');
const msg = t('sys.api.errorMessage');
createMessage.error(msg);
Promise.reject(new Error(msg));
}
......@@ -84,9 +84,9 @@ const transform: AxiosTransform = {
}
// 登录超时
if (code === ResultEnum.TIMEOUT) {
const timeoutMsg = t('timeoutMessage');
const timeoutMsg = t('sys.api.timeoutMessage');
createErrorModal({
title: t('operationFailed'),
title: t('sys.api.operationFailed'),
content: timeoutMsg,
});
Promise.reject(new Error(timeoutMsg));
......@@ -154,7 +154,7 @@ const transform: AxiosTransform = {
* @description: 响应错误处理
*/
responseInterceptorsCatch: (error: any) => {
const { t } = useI18n('sys.api');
const { t } = useI18n();
errorStore.setupErrorHandle(error);
const { response, code, message } = error || {};
const msg: string =
......@@ -162,12 +162,12 @@ const transform: AxiosTransform = {
const err: string = error.toString();
try {
if (code === 'ECONNABORTED' && message.indexOf('timeout') !== -1) {
createMessage.error(t('apiTimeoutMessage'));
createMessage.error(t('sys.api.apiTimeoutMessage'));
}
if (err && err.includes('Network Error')) {
createErrorModal({
title: t('networkException'),
content: t('networkExceptionMsg'),
title: t('sys.api.networkException'),
content: t('sys.api.networkExceptionMsg'),
});
}
} catch (error) {
......
<template>
<BasicModal :width="800" :title="t('tableActionDesc')" v-bind="$attrs">
<BasicModal :width="800" :title="t('sys.errorLog.tableActionDesc')" v-bind="$attrs">
<Description :data="info" @register="register" />
</BasicModal>
</template>
......@@ -23,7 +23,7 @@
},
},
setup() {
const { t } = useI18n('sys.errorLog');
const { t } = useI18n();
const [register] = useDescription({
column: 2,
schema: getDescSchema(),
......
......@@ -3,13 +3,13 @@ import { BasicColumn } from '/@/components/Table/index';
import { ErrorTypeEnum } from '/@/enums/exceptionEnum';
import { useI18n } from '/@/hooks/web/useI18n';
const { t } = useI18n('sys.errorLog');
const { t } = useI18n();
export function getColumns(): BasicColumn[] {
return [
{
dataIndex: 'type',
title: t('tableColumnType'),
title: t('sys.errorLog.tableColumnType'),
width: 80,
customRender: ({ text }) => {
const color =
......@@ -32,12 +32,12 @@ export function getColumns(): BasicColumn[] {
},
{
dataIndex: 'time',
title: t('tableColumnDate'),
title: t('sys.errorLog.tableColumnDate'),
width: 160,
},
{
dataIndex: 'file',
title: t('tableColumnFile'),
title: t('sys.errorLog.tableColumnFile'),
width: 200,
},
{
......@@ -47,12 +47,12 @@ export function getColumns(): BasicColumn[] {
},
{
dataIndex: 'message',
title: t('tableColumnMsg'),
title: t('sys.errorLog.tableColumnMsg'),
width: 300,
},
{
dataIndex: 'stack',
title: t('tableColumnStackMsg'),
title: t('sys.errorLog.tableColumnStackMsg'),
width: 300,
},
];
......
......@@ -53,7 +53,7 @@
const rowInfoRef = ref<ErrorInfo>();
const imgListRef = ref<string[]>([]);
const { t } = useI18n('sys.errorLog');
const { t } = useI18n();
const [register, { setTableData }] = useTable({
title: t('sys.errorLog.tableTitle'),
......@@ -80,7 +80,7 @@
);
const { createMessage } = useMessage();
if (isDevMode()) {
createMessage.info(t('enableMessage'));
createMessage.info(t('sys.errorLog.enableMessage'));
}
// 查看详情
function handleDetail(row: ErrorInfo) {
......
......@@ -53,7 +53,7 @@ export default defineComponent({
const { query } = useRoute();
const go = useGo();
const redo = useRedo();
const { t } = useI18n('sys.exception');
const { t } = useI18n();
const getStatus = computed(() => {
const { status: routeStatus } = query;
......@@ -67,13 +67,13 @@ export default defineComponent({
}
);
const backLoginI18n = t('backLogin');
const backHomeI18n = t('backHome');
const backLoginI18n = t('sys.exception.backLogin');
const backHomeI18n = t('sys.exception.backHome');
unref(statusMapRef).set(ExceptionEnum.PAGE_NOT_ACCESS, {
title: '403',
status: `${ExceptionEnum.PAGE_NOT_ACCESS}`,
subTitle: t('subTitle403'),
subTitle: t('sys.exception.subTitle403'),
btnText: props.full ? backLoginI18n : backHomeI18n,
handler: () => (props.full ? go(PageEnum.BASE_LOGIN) : go()),
});
......@@ -81,7 +81,7 @@ export default defineComponent({
unref(statusMapRef).set(ExceptionEnum.PAGE_NOT_FOUND, {
title: '404',
status: `${ExceptionEnum.PAGE_NOT_FOUND}`,
subTitle: t('subTitle404'),
subTitle: t('sys.exception.subTitle404'),
btnText: props.full ? backLoginI18n : backHomeI18n,
handler: () => (props.full ? go(PageEnum.BASE_LOGIN) : go()),
});
......@@ -89,22 +89,22 @@ export default defineComponent({
unref(statusMapRef).set(ExceptionEnum.ERROR, {
title: '500',
status: `${ExceptionEnum.ERROR}`,
subTitle: t('subTitle500'),
subTitle: t('sys.exception.subTitle500'),
btnText: backHomeI18n,
handler: () => go(),
});
unref(statusMapRef).set(ExceptionEnum.PAGE_NOT_DATA, {
title: t('noDataTitle'),
title: t('sys.exception.noDataTitle'),
subTitle: '',
btnText: t('redo'),
btnText: t('sys.exception.redo'),
handler: () => redo(),
icon: notDataImg,
});
unref(statusMapRef).set(ExceptionEnum.NET_WORK_ERROR, {
title: t('networkErrorTitle'),
subTitle: t('networkErrorSubTitle'),
title: t('sys.exception.networkErrorTitle'),
subTitle: t('sys.exception.networkErrorSubTitle'),
btnText: 'Refresh',
handler: () => redo(),
icon: netWorkImg,
......
......@@ -36,7 +36,7 @@
const loadingRef = ref(false);
const errMsgRef = ref(false);
const { t } = useI18n('sys.lock');
const { t } = useI18n();
const [register, { validateFields }] = useForm({
showActionButtonGroup: false,
schemas: [
......@@ -46,7 +46,7 @@
component: 'InputPassword',
componentProps: {
style: { width: '100%' },
placeholder: t('placeholder'),
placeholder: t('sys.lock.placeholder'),
},
rules: [{ required: true }],
},
......
......@@ -90,7 +90,7 @@
const globSetting = useGlobSetting();
const { locale } = useProjectSetting();
const { notification } = useMessage();
const { t } = useI18n('sys.login');
const { t } = useI18n();
// const openLoginVerifyRef = computed(() => appStore.getProjectConfig.openLoginVerify);
......@@ -104,8 +104,10 @@
});
const formRules = reactive({
account: [{ required: true, message: t('accountPlaceholder'), trigger: 'blur' }],
password: [{ required: true, message: t('passwordPlaceholder'), trigger: 'blur' }],
account: [{ required: true, message: t('sys.login.accountPlaceholder'), trigger: 'blur' }],
password: [
{ required: true, message: t('sys.login.passwordPlaceholder'), trigger: 'blur' },
],
// verify: unref(openLoginVerifyRef) ? [{ required: true, message: '请通过验证码校验' }] : [],
});
......@@ -130,8 +132,8 @@
);
if (userInfo) {
notification.success({
message: t('loginSuccessTitle'),
description: `${t('loginSuccessDesc')}: ${userInfo.realName}`,
message: t('sys.login.loginSuccessTitle'),
description: `${t('sys.login.loginSuccessDesc')}: ${userInfo.realName}`,
duration: 3,
});
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册