diff --git a/README.md b/README.md
index 170bc7e3..19c8705c 100644
--- a/README.md
+++ b/README.md
@@ -352,7 +352,7 @@ console.log(t('common.confirm'));
## 💬 交流群
-
+
## 🧧 捐献作者
@@ -389,4 +389,19 @@ console.log(t('common.confirm'));
DAS 20元
-
\ No newline at end of file
+
+
+
+

+
大山 100元
+
+
+
+

+
依依 20元
+
+
+
+

+
沙海 20元
+
diff --git a/docs/template/index-tree.vue.vm b/docs/template/index-tree.vue.vm
index b187996c..0ab2b7b7 100644
--- a/docs/template/index-tree.vue.vm
+++ b/docs/template/index-tree.vue.vm
@@ -205,6 +205,7 @@ function handleExport() {
:columns="columns"
:data="data"
size="small"
+ :indent="32"
:flex-height="!appStore.isMobile"
:scroll-x="962"
:loading="loading"
diff --git a/src/components/custom/menu-tree.vue b/src/components/custom/menu-tree.vue
index 7f9e52be..fdb9960f 100644
--- a/src/components/custom/menu-tree.vue
+++ b/src/components/custom/menu-tree.vue
@@ -21,11 +21,10 @@ const { bool: checkAll } = useBoolean();
const expandedKeys = ref([0]);
const menuTreeRef = ref(null);
-const value = defineModel('value', { required: false, default: [] });
+const checkedKeys = defineModel('checkedKeys', { required: false, default: [] });
const options = defineModel('options', { required: false, default: [] });
const cascade = defineModel('cascade', { required: false, default: true });
const loading = defineModel('loading', { required: false, default: false });
-
const attrs: TreeSelectProps = useAttrs();
async function getMenuList() {
@@ -83,14 +82,14 @@ function getAllMenuIds(menu: Api.System.MenuList) {
function handleCheckedTreeNodeAll(checked: boolean) {
if (checked) {
- value.value = getAllMenuIds(options.value);
+ checkedKeys.value = getAllMenuIds(options.value);
return;
}
- value.value = [];
+ checkedKeys.value = [];
}
-function handleSubmit() {
- const menuIds = [...value.value];
+function getCheckedMenuIds() {
+ const menuIds = menuTreeRef.value?.getCheckedData()?.keys as string[];
const indeterminateData = menuTreeRef.value?.getIndeterminateData();
if (cascade.value) {
const parentIds: string[] = indeterminateData?.keys.filter(item => !menuIds?.includes(String(item))) as string[];
@@ -100,7 +99,7 @@ function handleSubmit() {
}
defineExpose({
- submit: handleSubmit,
+ getCheckedMenuIds,
refresh: getMenuList
});
@@ -122,7 +121,7 @@ defineExpose({
-
+ !authStore.loginLoading && handleSubmit()"
+ >
();
const captchaEnabled = ref(false);
@@ -25,7 +26,8 @@ const model: Api.Auth.RegisterForm = reactive({
username: '',
code: '',
password: '',
- confirmPassword: ''
+ confirmPassword: '',
+ userType: 'sys_user'
});
type RuleKey = Extract;
@@ -43,9 +45,9 @@ const rules = computed>(() => {
});
async function handleSubmit() {
- await validate();
try {
- // request to register
+ await validate();
+ startRegisterLoading();
const { error } = await fetchRegister({
tenantId: model.tenantId,
username: model.username,
@@ -53,12 +55,20 @@ async function handleSubmit() {
code: model.code,
uuid: model.uuid,
grantType: 'password',
+ userType: model.userType,
clientId: import.meta.env.VITE_APP_CLIENT_ID
});
- if (error) return;
+ if (error) {
+ handleFetchCaptchaCode();
+ return;
+ }
window.$message?.success('注册成功');
+ // 注册成功后跳转到登录页
+ toggleLoginModule('pwd-login');
} catch {
handleFetchCaptchaCode();
+ } finally {
+ endRegisterLoading();
}
}
@@ -93,9 +103,16 @@ handleFetchCaptchaCode();
-
+ !registerLoading && handleSubmit()"
+ >
-
+
@@ -128,7 +145,7 @@ handleFetchCaptchaCode();
-
+
{{ $t('page.login.common.register') }}
diff --git a/src/views/system/menu/index.vue b/src/views/system/menu/index.vue
index 731bc88e..c710d51d 100644
--- a/src/views/system/menu/index.vue
+++ b/src/views/system/menu/index.vue
@@ -46,7 +46,7 @@ const getMeunTree = async () => {
treeData.value = [
{
menuId: 0,
- menuName: '根目录',
+ menuName: $t('page.system.menu.rootName'),
icon: 'material-symbols:home-outline-rounded',
children: handleTree(data, { idField: 'menuId', filterFn: item => item.menuType !== 'F' })
}
@@ -112,7 +112,7 @@ function renderSuffix({ option }: { option: TreeOption }) {
text
class="h-18px"
icon="ic-round-plus"
- tooltip-content="新增子菜单"
+ tooltip-content={$t('page.system.menu.addChildMenu')}
onClick={(event: Event) => {
event.stopPropagation();
handleAddMenu(option.menuId as CommonType.IdType);
@@ -203,18 +203,18 @@ const btnColumns: DataTableColumns = [
}
},
{
- title: '权限名称',
+ title: $t('page.system.menu.menuName'),
key: 'menuName',
minWidth: 120
},
{
- title: '权限标识',
+ title: $t('page.system.menu.perms'),
key: 'perms',
align: 'center',
minWidth: 120
},
{
- title: '状态',
+ title: $t('page.system.menu.status'),
key: 'status',
minWidth: 80,
align: 'center',
@@ -223,13 +223,13 @@ const btnColumns: DataTableColumns = [
}
},
{
- title: '创建时间',
+ title: $t('page.system.menu.createTime'),
key: 'createTime',
align: 'center',
minWidth: 150
},
{
- title: '操作',
+ title: $t('common.action'),
key: 'actions',
width: 80,
align: 'center',
@@ -286,27 +286,27 @@ const btnColumns: DataTableColumns = [
- 菜单列表
+ {{ $t('page.system.menu.title') }}
-
+
= [
@update:selected-keys="(_: Array, option: Array) => handleClickTree(option)"
>
-
+
@@ -338,7 +338,7 @@ const btnColumns: DataTableColumns = [
= [
- 新增子菜单
+ {{ $t('page.system.menu.addChildMenu') }}
- 编辑
+ {{ $t('common.edit') }}
handleDeleteMenu()">
@@ -391,46 +391,50 @@ const btnColumns: DataTableColumns = [
label-class="w-20% min-w-88px"
content-class="w-100px"
>
-
+
{{ menuTypeRecord[currentMenu.menuType!] }}
-
+
- {{ currentMenu.menuName }}
-
+
+ {{ currentMenu.menuName }}
+
+
{{ currentMenu.component }}
-
+
{{ currentMenu.path }}
{{ currentMenu.queryParam }}
-
+
{{ currentMenu.perms }}
-
+
{{ menuIsFrameRecord[currentMenu.isFrame] }}
-
+
-
+
- {{ currentMenu.isCache === '0' ? '缓存' : '不缓存' }}
+ {{ currentMenu.isCache === '0' ? $t('page.system.menu.cache') : $t('page.system.menu.noCache') }}
= [
size="small"
icon="ic-round-refresh"
class="h-28px text-icon"
- tooltip-content="刷新"
+ :tooltip-content="$t('common.refresh')"
@click.stop="getBtnMenuList"
/>
diff --git a/src/views/system/menu/modules/menu-operate-drawer.vue b/src/views/system/menu/modules/menu-operate-drawer.vue
index 86b41371..65b57f05 100644
--- a/src/views/system/menu/modules/menu-operate-drawer.vue
+++ b/src/views/system/menu/modules/menu-operate-drawer.vue
@@ -45,8 +45,8 @@ const queryList = ref<{ key: string; value: string }[]>([]);
const drawerTitle = computed(() => {
const titles: Record
= {
- add: '新增菜单',
- edit: '编辑菜单'
+ add: $t('page.system.menu.addMenu'),
+ edit: $t('page.system.menu.editMenu')
};
return titles[props.operateType];
});
@@ -69,7 +69,7 @@ function createDefaultModel(): Model {
visible: '0',
status: '0',
perms: '',
- icon: '',
+ icon: undefined,
remark: ''
};
}
@@ -77,10 +77,10 @@ function createDefaultModel(): Model {
type RuleKey = Extract;
const rules: Record = {
- menuName: createRequiredRule('菜单名称不能为空'),
- orderNum: createNumberRequiredRule('菜单排序不能为空'),
- path: createRequiredRule('路由地址不能为空'),
- component: createRequiredRule('组件路径不能为空')
+ menuName: createRequiredRule($t('page.system.menu.form.menuName.invalid')),
+ orderNum: createNumberRequiredRule($t('page.system.menu.form.orderNum.invalid')),
+ path: createRequiredRule($t('page.system.menu.form.path.invalid')),
+ component: createRequiredRule($t('page.system.menu.form.component.invalid'))
};
const isBtn = computed(() => model.menuType === 'F');
@@ -228,17 +228,22 @@ function onCreate() {
-
+
-
+
-
-
+
+
-
+
@@ -259,40 +264,51 @@ function onCreate() {
-
- 菜单图标
+
+ {{ $t('page.system.menu.icon') }}
-
+
-
+
-
- {{ model.isFrame !== '0' ? '路由地址' : '外链地址' }}
+
+
+ {{ model.isFrame !== '0' ? $t('page.system.menu.path') : $t('page.system.menu.externalPath') }}
+
-
+
-
- 组件路径
+
+ {{ $t('page.system.menu.component') }}
views/
-
+
/index.vue
@@ -300,7 +316,7 @@ function onCreate() {
v-if="isMenu && model.isFrame !== '0'"
span="24"
:show-feedback="!queryList.length"
- :label="model.isFrame !== '2' ? '路由参数' : 'iframe 地址'"
+ :label="model.isFrame !== '2' ? $t('page.system.menu.query') : $t('page.system.menu.iframeQuery')"
>
@@ -325,29 +344,36 @@ function onCreate() {
ignore-path-change
:show-label="false"
:path="`query[${index}].value`"
- :rule="{ ...createRequiredRule('请输入 Value'), validator: value => isNotNull(value) }"
+ :rule="{
+ ...createRequiredRule($t('page.system.menu.placeholder.queryValue')),
+ validator: value => isNotNull(value)
+ }"
>
-
+
-
- 权限字符
+
+ {{ $t('page.system.menu.perms') }}
-
+
-
- 是否外链
+
+ {{ $t('page.system.menu.isFrame') }}
@@ -364,8 +390,8 @@ function onCreate() {
-
- 是否缓存
+
+ {{ $t('page.system.menu.isCache') }}
@@ -375,11 +401,11 @@ function onCreate() {
-
+
-
- 显示状态
+
+ {{ $t('page.system.menu.visible') }}
@@ -387,14 +413,14 @@ function onCreate() {
-
- 菜单状态
+
+ {{ $t('page.system.menu.status') }}
-
-
+
+
diff --git a/src/views/system/role/modules/role-operate-drawer.vue b/src/views/system/role/modules/role-operate-drawer.vue
index 79119a18..389bdce0 100644
--- a/src/views/system/role/modules/role-operate-drawer.vue
+++ b/src/views/system/role/modules/role-operate-drawer.vue
@@ -102,9 +102,8 @@ function closeDrawer() {
async function handleSubmit() {
await validate();
-
- const { roleId, roleName, roleKey, roleSort, menuCheckStrictly, status, remark, menuIds } = model;
-
+ const { roleId, roleName, roleKey, roleSort, menuCheckStrictly, status, remark } = model;
+ const menuIds = menuTreeRef.value?.getCheckedMenuIds();
// request
if (props.operateType === 'add') {
const { error } = await fetchCreateRole({
@@ -174,7 +173,7 @@ watch(visible, () => {
{