This is an automated email from the ASF dual-hosted git repository.

yuzelin pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-paimon-webui.git


The following commit(s) were added to refs/heads/main by this push:
     new 01ac555  [Feature] Added Login Page (#30)
01ac555 is described below

commit 01ac5551d8d0142f300cb6795fad6932502baa5f
Author: zhu-mingye <[email protected]>
AuthorDate: Wed Aug 23 10:22:45 2023 +0800

    [Feature] Added Login Page (#30)
---
 paimon-web-api/pom.xml                             |   1 +
 paimon-web-server/pom.xml                          |   5 +
 .../web/server/controller/LoginController.java     |   6 +-
 .../web/server/data/result/enums/Status.java       |   1 +
 .../user/UserNotBindTenantException.java}          |  20 ++--
 .../paimon/web/server/data/vo/UserInfoVo.java      |  47 ++++++++
 .../paimon/web/server/service/RoleMenuService.java |  27 +++++
 .../paimon/web/server/service/SysMenuService.java  |   4 +-
 .../paimon/web/server/service/TenantService.java   |  27 +++++
 .../paimon/web/server/service/UserRoleService.java |  33 +++++
 .../paimon/web/server/service/UserService.java     |   5 +-
 .../web/server/service/UserTenantService.java      |  27 +++++
 .../server/service/impl/RoleMenuServiceImpl.java   |  32 +++++
 .../web/server/service/impl/TenantServiceImpl.java |  31 +++++
 .../server/service/impl/UserRoleServiceImpl.java   |  42 +++++++
 .../web/server/service/impl/UserServiceImpl.java   |  75 +++++++++++-
 .../server/service/impl/UserTenantServiceImpl.java |  32 +++++
 .../src/main/resources/application-prod.yml        |   6 +-
 .../src/main/resources/application.yml             |   9 +-
 .../src/main/resources/i18n/messages.properties    |   1 +
 .../main/resources/i18n/messages_en_US.properties  |   1 +
 .../main/resources/i18n/messages_zh_CN.properties  |  37 +++---
 paimon-web-ui/package.json                         |   7 +-
 paimon-web-ui/src/api/endpoints.ts                 |   6 +
 paimon-web-ui/src/api/http.ts                      |  49 ++++++--
 paimon-web-ui/src/pages/Other/Login/index.tsx      | 133 +++++++++++++++++++++
 paimon-web-ui/src/router/index.tsx                 |   9 ++
 paimon-web-ui/src/types/Public/data.d.ts           |  48 ++++++++
 paimon-web-ui/src/types/User/data.d.ts             | 104 ++++++++++++++++
 pom.xml                                            |   7 ++
 30 files changed, 778 insertions(+), 54 deletions(-)

diff --git a/paimon-web-api/pom.xml b/paimon-web-api/pom.xml
index 24f8c1c..121820a 100644
--- a/paimon-web-api/pom.xml
+++ b/paimon-web-api/pom.xml
@@ -28,6 +28,7 @@ under the License.
     </parent>
 
     <artifactId>paimon-web-api</artifactId>
+    <name>Paimon : Web : Api</name>
 
     <properties>
         <maven.compiler.source>8</maven.compiler.source>
diff --git a/paimon-web-server/pom.xml b/paimon-web-server/pom.xml
index ca9b0ac..3c4fa57 100644
--- a/paimon-web-server/pom.xml
+++ b/paimon-web-server/pom.xml
@@ -51,6 +51,11 @@ under the License.
             <version>${project.version}</version>
         </dependency>
 
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+        </dependency>
+
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-configuration-processor</artifactId>
diff --git 
a/paimon-web-server/src/main/java/org/apache/paimon/web/server/controller/LoginController.java
 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/controller/LoginController.java
index b209464..c9ff128 100644
--- 
a/paimon-web-server/src/main/java/org/apache/paimon/web/server/controller/LoginController.java
+++ 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/controller/LoginController.java
@@ -20,13 +20,13 @@ package org.apache.paimon.web.server.controller;
 
 import org.apache.paimon.web.server.data.dto.LoginDto;
 import org.apache.paimon.web.server.data.result.R;
+import org.apache.paimon.web.server.data.vo.UserInfoVo;
 import org.apache.paimon.web.server.service.UserService;
 
 import cn.dev33.satoken.stp.SaTokenInfo;
 import cn.dev33.satoken.stp.StpUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
@@ -48,7 +48,7 @@ public class LoginController {
      * @return token string
      */
     @PostMapping("/login")
-    public R<String> login(@Validated @RequestBody LoginDto loginDto) {
+    public R<UserInfoVo> login(@RequestBody LoginDto loginDto) {
         return R.succeed(userService.login(loginDto));
     }
 
@@ -65,7 +65,7 @@ public class LoginController {
     /** logout. */
     @PostMapping("/logout")
     public R<Void> logout() {
-        StpUtil.logout();
+        StpUtil.logout(StpUtil.getLoginIdAsInt());
         return R.succeed();
     }
 }
diff --git 
a/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/result/enums/Status.java
 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/result/enums/Status.java
index 27283ba..9f1209f 100644
--- 
a/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/result/enums/Status.java
+++ 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/result/enums/Status.java
@@ -43,6 +43,7 @@ public enum Status {
     USER_NOT_EXIST(10001, "user.not.exist"),
     USER_PASSWORD_ERROR(10002, "user.password.error"),
     USER_DISABLED_ERROR(10003, "user.is.disabled"),
+    USER_NOT_BING_TENANT(10004, "user.not.bing.tenant"),
     /** ------------role-----------------. */
     ROLE_IN_USED(10101, "role.in.used"),
     ROLE_NAME_IS_EXIST(10102, "role.name.exist"),
diff --git 
a/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/dto/UserDto.java
 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/result/exception/user/UserNotBindTenantException.java
similarity index 64%
rename from 
paimon-web-server/src/main/java/org/apache/paimon/web/server/data/dto/UserDto.java
rename to 
paimon-web-server/src/main/java/org/apache/paimon/web/server/data/result/exception/user/UserNotBindTenantException.java
index fdcd279..8cc858d 100644
--- 
a/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/dto/UserDto.java
+++ 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/result/exception/user/UserNotBindTenantException.java
@@ -16,18 +16,16 @@
  * limitations under the License.
  */
 
-package org.apache.paimon.web.server.data.dto;
+package org.apache.paimon.web.server.data.result.exception.user;
 
-import org.apache.paimon.web.server.data.model.Tenant;
-import org.apache.paimon.web.server.data.model.User;
+import org.apache.paimon.web.server.data.result.enums.Status;
+import org.apache.paimon.web.server.data.result.exception.BaseException;
 
-import lombok.Data;
+/** Exception to user not bind tenant. */
+public class UserNotBindTenantException extends BaseException {
+    private static final long serialVersionUID = 1L;
 
-import java.util.List;
-
-/** user data transfer object. */
-@Data
-public class UserDto {
-    private User user;
-    private List<Tenant> tenantList;
+    public UserNotBindTenantException() {
+        super(Status.USER_DISABLED_ERROR);
+    }
 }
diff --git 
a/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/UserInfoVo.java
 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/UserInfoVo.java
new file mode 100644
index 0000000..fdd08e2
--- /dev/null
+++ 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/data/vo/UserInfoVo.java
@@ -0,0 +1,47 @@
+/*
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements.  See the NOTICE file distributed with
+ *   this work for additional information regarding copyright ownership.
+ *   The ASF licenses this file to You under the Apache License, Version 2.0
+ *   (the "License"); you may not use this file except in compliance with
+ *   the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+package org.apache.paimon.web.server.data.vo;
+
+import org.apache.paimon.web.server.data.model.SysMenu;
+import org.apache.paimon.web.server.data.model.SysRole;
+import org.apache.paimon.web.server.data.model.Tenant;
+import org.apache.paimon.web.server.data.model.User;
+
+import cn.dev33.satoken.stp.SaTokenInfo;
+import lombok.Data;
+
+import java.util.List;
+
+/** user data transfer object. */
+@Data
+public class UserInfoVo {
+    /** current user info. */
+    private User user;
+    /** current user's tenant list. */
+    private List<Tenant> tenantList;
+    /** current user's role list. */
+    private List<SysRole> roleList;
+    /** current user's token info. */
+    private SaTokenInfo saTokenInfo;
+    /** current user's menu list. */
+    private List<SysMenu> sysMenuList;
+    /** current user's tenant. */
+    private Tenant currentTenant;
+}
diff --git 
a/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/RoleMenuService.java
 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/RoleMenuService.java
new file mode 100644
index 0000000..93cd92d
--- /dev/null
+++ 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/RoleMenuService.java
@@ -0,0 +1,27 @@
+/*
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements.  See the NOTICE file distributed with
+ *   this work for additional information regarding copyright ownership.
+ *   The ASF licenses this file to You under the Apache License, Version 2.0
+ *   (the "License"); you may not use this file except in compliance with
+ *   the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+package org.apache.paimon.web.server.service;
+
+import org.apache.paimon.web.server.data.model.RoleMenu;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/** RoleMenu Service. */
+public interface RoleMenuService extends IService<RoleMenu> {}
diff --git 
a/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/SysMenuService.java
 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/SysMenuService.java
index c75590b..4bc9072 100644
--- 
a/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/SysMenuService.java
+++ 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/SysMenuService.java
@@ -22,11 +22,13 @@ import org.apache.paimon.web.server.data.model.SysMenu;
 import org.apache.paimon.web.server.data.tree.TreeSelect;
 import org.apache.paimon.web.server.data.vo.RouterVo;
 
+import com.baomidou.mybatisplus.extension.service.IService;
+
 import java.util.List;
 import java.util.Set;
 
 /** Menu service. */
-public interface SysMenuService {
+public interface SysMenuService extends IService<SysMenu> {
     /**
      * Query menu list by user.
      *
diff --git 
a/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/TenantService.java
 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/TenantService.java
new file mode 100644
index 0000000..8fe26db
--- /dev/null
+++ 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/TenantService.java
@@ -0,0 +1,27 @@
+/*
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements.  See the NOTICE file distributed with
+ *   this work for additional information regarding copyright ownership.
+ *   The ASF licenses this file to You under the Apache License, Version 2.0
+ *   (the "License"); you may not use this file except in compliance with
+ *   the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+package org.apache.paimon.web.server.service;
+
+import org.apache.paimon.web.server.data.model.Tenant;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/** Tenant Service. */
+public interface TenantService extends IService<Tenant> {}
diff --git 
a/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/UserRoleService.java
 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/UserRoleService.java
new file mode 100644
index 0000000..f51bd62
--- /dev/null
+++ 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/UserRoleService.java
@@ -0,0 +1,33 @@
+/*
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements.  See the NOTICE file distributed with
+ *   this work for additional information regarding copyright ownership.
+ *   The ASF licenses this file to You under the Apache License, Version 2.0
+ *   (the "License"); you may not use this file except in compliance with
+ *   the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+package org.apache.paimon.web.server.service;
+
+import org.apache.paimon.web.server.data.model.User;
+import org.apache.paimon.web.server.data.model.UserRole;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import java.util.List;
+
+/** UserRole Service. */
+public interface UserRoleService extends IService<UserRole> {
+
+    List<UserRole> selectUserRoleListByUserId(User user);
+}
diff --git 
a/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/UserService.java
 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/UserService.java
index c6ed35e..04ef546 100644
--- 
a/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/UserService.java
+++ 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/UserService.java
@@ -21,6 +21,7 @@ package org.apache.paimon.web.server.service;
 import org.apache.paimon.web.server.data.dto.LoginDto;
 import org.apache.paimon.web.server.data.model.User;
 import org.apache.paimon.web.server.data.result.exception.BaseException;
+import org.apache.paimon.web.server.data.vo.UserInfoVo;
 
 import com.baomidou.mybatisplus.extension.service.IService;
 
@@ -32,10 +33,10 @@ public interface UserService extends IService<User> {
     /**
      * login by username and password.
      *
-     * @param loginDto login info
+     * @param loginDto login params
      * @return {@link String}
      */
-    String login(LoginDto loginDto) throws BaseException;
+    UserInfoVo login(LoginDto loginDto) throws BaseException;
 
     /**
      * Query the list of assigned user roles.
diff --git 
a/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/UserTenantService.java
 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/UserTenantService.java
new file mode 100644
index 0000000..f55bbaa
--- /dev/null
+++ 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/UserTenantService.java
@@ -0,0 +1,27 @@
+/*
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements.  See the NOTICE file distributed with
+ *   this work for additional information regarding copyright ownership.
+ *   The ASF licenses this file to You under the Apache License, Version 2.0
+ *   (the "License"); you may not use this file except in compliance with
+ *   the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+package org.apache.paimon.web.server.service;
+
+import org.apache.paimon.web.server.data.model.UserTenant;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/** Tenant Service. */
+public interface UserTenantService extends IService<UserTenant> {}
diff --git 
a/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/impl/RoleMenuServiceImpl.java
 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/impl/RoleMenuServiceImpl.java
new file mode 100644
index 0000000..0ead095
--- /dev/null
+++ 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/impl/RoleMenuServiceImpl.java
@@ -0,0 +1,32 @@
+/*
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements.  See the NOTICE file distributed with
+ *   this work for additional information regarding copyright ownership.
+ *   The ASF licenses this file to You under the Apache License, Version 2.0
+ *   (the "License"); you may not use this file except in compliance with
+ *   the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+package org.apache.paimon.web.server.service.impl;
+
+import org.apache.paimon.web.server.data.model.RoleMenu;
+import org.apache.paimon.web.server.mapper.RoleMenuMapper;
+import org.apache.paimon.web.server.service.RoleMenuService;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/** RoleMenuServiceImpl. */
+@Service
+public class RoleMenuServiceImpl extends ServiceImpl<RoleMenuMapper, RoleMenu>
+        implements RoleMenuService {}
diff --git 
a/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/impl/TenantServiceImpl.java
 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/impl/TenantServiceImpl.java
new file mode 100644
index 0000000..a2e06bd
--- /dev/null
+++ 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/impl/TenantServiceImpl.java
@@ -0,0 +1,31 @@
+/*
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements.  See the NOTICE file distributed with
+ *   this work for additional information regarding copyright ownership.
+ *   The ASF licenses this file to You under the Apache License, Version 2.0
+ *   (the "License"); you may not use this file except in compliance with
+ *   the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+package org.apache.paimon.web.server.service.impl;
+
+import org.apache.paimon.web.server.data.model.Tenant;
+import org.apache.paimon.web.server.mapper.TenantMapper;
+import org.apache.paimon.web.server.service.TenantService;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/** TenantServiceImpl. */
+@Service
+public class TenantServiceImpl extends ServiceImpl<TenantMapper, Tenant> 
implements TenantService {}
diff --git 
a/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/impl/UserRoleServiceImpl.java
 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/impl/UserRoleServiceImpl.java
new file mode 100644
index 0000000..6f6ca1f
--- /dev/null
+++ 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/impl/UserRoleServiceImpl.java
@@ -0,0 +1,42 @@
+/*
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements.  See the NOTICE file distributed with
+ *   this work for additional information regarding copyright ownership.
+ *   The ASF licenses this file to You under the Apache License, Version 2.0
+ *   (the "License"); you may not use this file except in compliance with
+ *   the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+package org.apache.paimon.web.server.service.impl;
+
+import org.apache.paimon.web.server.data.model.User;
+import org.apache.paimon.web.server.data.model.UserRole;
+import org.apache.paimon.web.server.mapper.UserRoleMapper;
+import org.apache.paimon.web.server.service.UserRoleService;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/** UserRoleServiceImpl. */
+@Service
+public class UserRoleServiceImpl extends ServiceImpl<UserRoleMapper, UserRole>
+        implements UserRoleService {
+
+    @Override
+    public List<UserRole> selectUserRoleListByUserId(User user) {
+        return list(new LambdaQueryWrapper<UserRole>().eq(UserRole::getUserId, 
user.getId()));
+    }
+}
diff --git 
a/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/impl/UserServiceImpl.java
 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/impl/UserServiceImpl.java
index 5d66c7f..6cae557 100644
--- 
a/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/impl/UserServiceImpl.java
+++ 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/impl/UserServiceImpl.java
@@ -20,20 +20,35 @@ package org.apache.paimon.web.server.service.impl;
 
 import org.apache.paimon.web.server.data.dto.LoginDto;
 import org.apache.paimon.web.server.data.enums.UserType;
+import org.apache.paimon.web.server.data.model.RoleMenu;
+import org.apache.paimon.web.server.data.model.SysMenu;
+import org.apache.paimon.web.server.data.model.SysRole;
 import org.apache.paimon.web.server.data.model.User;
+import org.apache.paimon.web.server.data.model.UserRole;
 import org.apache.paimon.web.server.data.result.exception.BaseException;
 import 
org.apache.paimon.web.server.data.result.exception.user.UserDisabledException;
+import 
org.apache.paimon.web.server.data.result.exception.user.UserNotBindTenantException;
 import 
org.apache.paimon.web.server.data.result.exception.user.UserNotExistsException;
 import 
org.apache.paimon.web.server.data.result.exception.user.UserPasswordNotMatchException;
+import org.apache.paimon.web.server.data.vo.UserInfoVo;
 import org.apache.paimon.web.server.mapper.UserMapper;
 import org.apache.paimon.web.server.service.LdapService;
+import org.apache.paimon.web.server.service.RoleMenuService;
+import org.apache.paimon.web.server.service.SysMenuService;
+import org.apache.paimon.web.server.service.SysRoleService;
+import org.apache.paimon.web.server.service.TenantService;
+import org.apache.paimon.web.server.service.UserRoleService;
 import org.apache.paimon.web.server.service.UserService;
 
+import cn.dev33.satoken.secure.SaSecureUtil;
 import cn.dev33.satoken.stp.StpUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Optional;
 
@@ -43,6 +58,11 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, 
User> implements Us
 
     @Autowired private LdapService ldapService;
     @Autowired private UserMapper userMapper;
+    @Autowired private UserRoleService userRoleService;
+    @Autowired private SysRoleService sysRoleService;
+    @Autowired private RoleMenuService roleMenuService;
+    @Autowired private SysMenuService sysMenuService;
+    @Autowired private TenantService tenantService;
 
     /**
      * login by username and password.
@@ -51,7 +71,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, 
User> implements Us
      * @return {@link String}
      */
     @Override
-    public String login(LoginDto loginDto) throws BaseException {
+    public UserInfoVo login(LoginDto loginDto) throws BaseException {
         String username = loginDto.getUsername();
         String password = loginDto.getPassword();
 
@@ -62,10 +82,55 @@ public class UserServiceImpl extends 
ServiceImpl<UserMapper, User> implements Us
         if (!user.getEnabled()) {
             throw new UserDisabledException();
         }
+        // query user info
+        UserInfoVo userInfoVo = getUserInfoVo(user);
+        if (CollectionUtils.isEmpty(userInfoVo.getTenantList())) {
+            throw new UserNotBindTenantException();
+        }
 
         StpUtil.login(user.getId(), loginDto.isRememberMe());
 
-        return StpUtil.getTokenValue();
+        return userInfoVo;
+    }
+
+    /**
+     * get user info. include user, role, menu. tenant.
+     *
+     * @param user user
+     * @return {@link UserInfoVo}
+     */
+    private UserInfoVo getUserInfoVo(User user) {
+        UserInfoVo userInfoVo = new UserInfoVo();
+        userInfoVo.setUser(user);
+        userInfoVo.setSaTokenInfo(StpUtil.getTokenInfo());
+
+        // get user role list
+        List<SysRole> sysRoles = new ArrayList<>();
+        List<UserRole> userRoleList = 
userRoleService.selectUserRoleListByUserId(user);
+
+        // get role list
+        userRoleList.forEach(
+                userRole -> {
+                    sysRoles.add(sysRoleService.getById(userRole.getRoleId()));
+                });
+        userInfoVo.setRoleList(sysRoles);
+        // get menu list
+        List<SysMenu> sysMenus = new ArrayList<>();
+        userRoleList.forEach(
+                userRole -> {
+                    roleMenuService
+                            .list(
+                                    new LambdaQueryWrapper<RoleMenu>()
+                                            .eq(RoleMenu::getRoleId, 
userRole.getRoleId()))
+                            .forEach(
+                                    roleMenu -> {
+                                        
sysMenus.add(sysMenuService.getById(roleMenu.getMenuId()));
+                                    });
+                });
+        userInfoVo.setSysMenuList(sysMenus);
+
+        userInfoVo.setCurrentTenant(tenantService.getById(1));
+        return userInfoVo;
     }
 
     private User localLogin(String username, String password) throws 
BaseException {
@@ -77,10 +142,12 @@ public class UserServiceImpl extends 
ServiceImpl<UserMapper, User> implements Us
         if (user == null) {
             throw new UserNotExistsException();
         }
-        if (!user.getPassword().equals(password)) {
+
+        if (SaSecureUtil.md5(password).equals(user.getPassword())) {
+            return user;
+        } else {
             throw new UserPasswordNotMatchException();
         }
-        return user;
     }
 
     private User ldapLogin(String username, String password) throws 
BaseException {
diff --git 
a/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/impl/UserTenantServiceImpl.java
 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/impl/UserTenantServiceImpl.java
new file mode 100644
index 0000000..ccf7c0c
--- /dev/null
+++ 
b/paimon-web-server/src/main/java/org/apache/paimon/web/server/service/impl/UserTenantServiceImpl.java
@@ -0,0 +1,32 @@
+/*
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements.  See the NOTICE file distributed with
+ *   this work for additional information regarding copyright ownership.
+ *   The ASF licenses this file to You under the Apache License, Version 2.0
+ *   (the "License"); you may not use this file except in compliance with
+ *   the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+package org.apache.paimon.web.server.service.impl;
+
+import org.apache.paimon.web.server.data.model.UserTenant;
+import org.apache.paimon.web.server.mapper.UserTenantMapper;
+import org.apache.paimon.web.server.service.UserTenantService;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/** UserTenantServiceImpl. */
+@Service
+public class UserTenantServiceImpl extends ServiceImpl<UserTenantMapper, 
UserTenant>
+        implements UserTenantService {}
diff --git a/paimon-web-server/src/main/resources/application-prod.yml 
b/paimon-web-server/src/main/resources/application-prod.yml
index 9e87e23..1337972 100644
--- a/paimon-web-server/src/main/resources/application-prod.yml
+++ b/paimon-web-server/src/main/resources/application-prod.yml
@@ -15,7 +15,7 @@
 
 spring:
   datasource:
-    url: 
jdbc:mysql://${MYSQL_ADDR:localhost:3306}/${MYSQL_DATABASE:paimon}?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
-    username: ${MYSQL_USERNAME:paimon}
-    password: ${MYSQL_PASSWORD:paimon@123}
+    url: 
jdbc:mysql://${MYSQL_ADDR:124.221.249.188:3887}/${MYSQL_DATABASE:paimon}?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
+    username: ${MYSQL_USERNAME:root}
+    password: ${MYSQL_PASSWORD:Zhumingye520!@#.}
     driver-class-name: com.mysql.cj.jdbc.Driver
\ No newline at end of file
diff --git a/paimon-web-server/src/main/resources/application.yml 
b/paimon-web-server/src/main/resources/application.yml
index 8bd64dc..688ffc3 100644
--- a/paimon-web-server/src/main/resources/application.yml
+++ b/paimon-web-server/src/main/resources/application.yml
@@ -22,7 +22,7 @@ spring:
   application:
     name: Paimon Web UI
   profiles:
-    active:  dev
+    active: dev
   messages:
     basename: i18n/messages
     encoding: UTF-8
@@ -59,4 +59,9 @@ sa-token:
   is-concurrent: true
   is-share: true
   token-style: uuid
-  is-log: false
\ No newline at end of file
+  is-log: false
+  is-print: false
+  is-read-cookie: true
+  is-write-header: true
+  is-read-header: true
+  is-read-body: true
\ No newline at end of file
diff --git a/paimon-web-server/src/main/resources/i18n/messages.properties 
b/paimon-web-server/src/main/resources/i18n/messages.properties
index 957a9fc..7c16a94 100644
--- a/paimon-web-server/src/main/resources/i18n/messages.properties
+++ b/paimon-web-server/src/main/resources/i18n/messages.properties
@@ -26,6 +26,7 @@ internal.server.error=Internal Server Error:{0}
 user.not.exist=User Not Exist
 user.password.error=User Password Error
 user.is.disabled=User Is Disabled
+user.not.bing.tenant=User Not Bing Tenant
 role.in.used=This role {0} is in used
 role.name.exist=This role name {0} is exist
 role.key.exist=This role key {0} is exist
diff --git 
a/paimon-web-server/src/main/resources/i18n/messages_en_US.properties 
b/paimon-web-server/src/main/resources/i18n/messages_en_US.properties
index df1cb11..f48cf18 100644
--- a/paimon-web-server/src/main/resources/i18n/messages_en_US.properties
+++ b/paimon-web-server/src/main/resources/i18n/messages_en_US.properties
@@ -26,6 +26,7 @@ internal.server.error=Internal Server Error:{0}
 user.not.exist=User Not Exist
 user.password.error=User Password Error
 user.is.disabled=User Is Disabled
+user.not.bing.tenant=User Not Bing Tenant
 role.in.used=This role {0} is in used
 role.name.exist=This role name {0} is exist
 role.key.exist=This role key {0} is exist
diff --git 
a/paimon-web-server/src/main/resources/i18n/messages_zh_CN.properties 
b/paimon-web-server/src/main/resources/i18n/messages_zh_CN.properties
index 98aa255..6ceb2d8 100644
--- a/paimon-web-server/src/main/resources/i18n/messages_zh_CN.properties
+++ b/paimon-web-server/src/main/resources/i18n/messages_zh_CN.properties
@@ -14,21 +14,22 @@
 #  See the License for the specific language governing permissions and
 #  limitations under the License.
 #
-successfully=请求成功
-failed=请求失败
-unauthorized=用户未登陆
-forbidden=用户无权限
-unknown.error=未知错误:{0}
-method.not.allowed=请求方法不支持
-invalid.request.parameter=请求参数 {0} 无效
-request.parameter.error=请求参数错误:{0}
-internal.server.error=服务器内部错误:{0}
-user.not.exist=用户不存在
-user.password.error=密码错误
-user.is.disabled=用户已禁用
-role.in.used=此角色{0}正在使用中
-role.name.exist=此角色名称{0}已使用
-role.key.exist=此角色关键字{0}已使用
-menu.in.used=此菜单正在使用中
-menu.name.exist=此菜单名称已存在:{0}
-menu.path.invalid=此菜单路径无效:{0}
+successfully=\u8BF7\u6C42\u6210\u529F
+failed=\u8BF7\u6C42\u5931\u8D25
+unauthorized=\u7528\u6237\u672A\u767B\u9646
+forbidden=\u7528\u6237\u65E0\u6743\u9650
+unknown.error=\u672A\u77E5\u9519\u8BEF:{0}
+method.not.allowed=\u8BF7\u6C42\u65B9\u6CD5\u4E0D\u652F\u6301
+invalid.request.parameter=\u8BF7\u6C42\u53C2\u6570 {0} \u65E0\u6548
+request.parameter.error=\u8BF7\u6C42\u53C2\u6570\u9519\u8BEF:{0}
+internal.server.error=\u670D\u52A1\u5668\u5185\u90E8\u9519\u8BEF:{0}
+user.not.exist=\u7528\u6237\u4E0D\u5B58\u5728
+user.password.error=\u5BC6\u7801\u9519\u8BEF
+user.is.disabled=\u7528\u6237\u5DF2\u7981\u7528
+user.not.bing.tenant=\u7528\u6237\u672A\u7ED1\u5B9A\u79DF\u6237
+role.in.used=\u6B64\u89D2\u8272{0}\u6B63\u5728\u4F7F\u7528\u4E2D
+role.name.exist=\u6B64\u89D2\u8272\u540D\u79F0{0}\u5DF2\u4F7F\u7528
+role.key.exist=\u6B64\u89D2\u8272\u5173\u952E\u5B57{0}\u5DF2\u4F7F\u7528
+menu.in.used=\u6B64\u83DC\u5355\u6B63\u5728\u4F7F\u7528\u4E2D
+menu.name.exist=\u6B64\u83DC\u5355\u540D\u79F0\u5DF2\u5B58\u5728:{0}
+menu.path.invalid=\u6B64\u83DC\u5355\u8DEF\u5F84\u65E0\u6548:{0}
diff --git a/paimon-web-ui/package.json b/paimon-web-ui/package.json
index 5916f82..2faecbb 100644
--- a/paimon-web-ui/package.json
+++ b/paimon-web-ui/package.json
@@ -21,6 +21,8 @@
     "i18next": "^23.4.4",
     "i18next-browser-languagedetector": "^7.1.0",
     "i18next-http-backend": "^2.2.1",
+    "antd": "^5.8.3",
+    "@ant-design/pro-components": "^2.6.3",
     "less": "^4.1.3",
     "monaco-editor": "^0.40.0",
     "react": "^18.2.0",
@@ -28,7 +30,10 @@
     "react-dom": "^18.2.0",
     "react-icons": "^4.10.1",
     "react-i18next": "^13.1.0",
-    "zustand": "^4.4.1"
+    "zustand": "^4.4.1",
+    "styled-components": "^6.0.0-rc.3",
+    "vite-plugin-semi-theme": "^0.5.0",
+    "screenfull": "^6.0.2"
   },
   "devDependencies": {
     "@types/node": "^20.3.2",
diff --git a/paimon-web-ui/src/api/endpoints.ts 
b/paimon-web-ui/src/api/endpoints.ts
index dc7a79f..1567581 100644
--- a/paimon-web-ui/src/api/endpoints.ts
+++ b/paimon-web-ui/src/api/endpoints.ts
@@ -16,8 +16,14 @@ specific language governing permissions and limitations
 under the License. */
 
 export const API_ENDPOINTS = {
+
+    // auth && login
+    GET_LDAP_ENABLE: '/ldap/enable',
+    LOGIN: '/login',
+
     // catalog
     CREATE_FILE_SYSTEM_CATALOG: '/catalog/createFilesystemCatalog',
     CREATE_HIVE_CATALOG: '/catalog/createHiveCatalog',
     GET_ALL_CATALOGS: '/catalog/getAllCatalogs',
+
 };
\ No newline at end of file
diff --git a/paimon-web-ui/src/api/http.ts b/paimon-web-ui/src/api/http.ts
index e1364c6..e46d663 100644
--- a/paimon-web-ui/src/api/http.ts
+++ b/paimon-web-ui/src/api/http.ts
@@ -16,6 +16,9 @@ specific language governing permissions and limitations
 under the License. */
 
 import axios, { AxiosResponse, AxiosError } from 'axios';
+import { Notification } from '@douyinfe/semi-ui';
+import {UserState} from "@src/types/User/data";
+import {Result} from "@src/types/Public/data";
 
 const httpClient = axios.create({
     baseURL: '/api',
@@ -29,10 +32,13 @@ const httpClient = axios.create({
 // request interceptor.
 httpClient.interceptors.request.use(
     (config: any) => {
+
+        console.log(localStorage.getItem('token'))
+
         // Here you can set request headers like:config.headers['Token'] = 
localStorage.getItem('Token').
-       /* config.headers = {
-            "Authorization": store.getState().user.token
-        }*/
+       config.headers = {
+            "Authorization": localStorage.getItem('token')
+        }
         return config;
     },
     (error: AxiosError) => {
@@ -45,7 +51,24 @@ httpClient.interceptors.request.use(
 // response interceptor.
 httpClient.interceptors.response.use(
     (response: AxiosResponse) => {
+
         // Here you can process the response data.
+        const { data: reponseData , config: reponseConfig} = response;
+
+        // 处理 config 获取 baseUrl 和 url  拼接 判断是登录接口 , 如果是 拿到相应的数据 存储到 
localStorage 中 并设置到请求头中
+        if (reponseConfig.url === '/login') {
+            // todo: has a bug
+            const {data} = reponseData as Result<UserState>
+            console.log('登录接口', data)
+            //todo: use store
+            localStorage.setItem('token', data.tokenInfo.tokenValue)
+        }
+
+        // Handle response data
+        Notification.error({
+            title: 'Error',
+            content: `${reponseData.msg}`
+        });
         return response;
     },
     (error: AxiosError) => {
@@ -55,27 +78,35 @@ httpClient.interceptors.response.use(
     }
 );
 
-const httpGet = async <T, E>(url: string, param?: E): Promise<T> => {
+const httpGet = async <T, E>(url: string, param?: E, beforeCallBack? : () => 
void , afterCallBack? : () => void): Promise<T> => {
+    beforeCallBack && beforeCallBack()
     const {data} = await httpClient.get<T>(url, {params: param})
+    afterCallBack && afterCallBack()
     return data
 }
 
-const httpPost = async <T, E>(url: string, param: E): Promise<T> => {
-    const {data} = await httpClient.post<T>(url, param)
+const httpPost = async <T, E>(url: string, body: E, beforeCallBack? : () => 
void , afterCallBack? : () => void): Promise<T> => {
+    beforeCallBack && beforeCallBack()
+    const {data} = await httpClient.post<T>(url, body)
+    afterCallBack && afterCallBack()
     return data
 }
 
-const httpDelete = async <T, E>(url: string, param: E): Promise<T> => {
+const httpDelete = async <T, E>(url: string, param: E ,beforeCallBack? : () => 
void , afterCallBack? : () => void): Promise<T> => {
+    beforeCallBack && beforeCallBack()
     const {data} = await httpClient.delete(url, {params: param})
+    afterCallBack && afterCallBack()
     return data
 }
 
-const httpFormPost = async <T, E>(url: string, params?: E): Promise<T> => {
-    const {data} = await httpClient.post(url, params, {
+const httpFormPost = async <T, E>(url: string, body?: E , beforeCallBack? : () 
=> void , afterCallBack? : () => void): Promise<T> => {
+    beforeCallBack && beforeCallBack()
+    const {data} = await httpClient.post(url, body, {
         headers: {
             'Content-Type': 'multipart/form-data'
         }
     })
+    afterCallBack && afterCallBack()
     return data
 }
 
diff --git a/paimon-web-ui/src/pages/Other/Login/index.tsx 
b/paimon-web-ui/src/pages/Other/Login/index.tsx
new file mode 100644
index 0000000..306d116
--- /dev/null
+++ b/paimon-web-ui/src/pages/Other/Login/index.tsx
@@ -0,0 +1,133 @@
+/*
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements.  See the NOTICE file distributed with
+ *   this work for additional information regarding copyright ownership.
+ *   The ASF licenses this file to You under the Apache License, Version 2.0
+ *   (the "License"); you may not use this file except in compliance with
+ *   the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+import {useEffect, useState} from "react";
+import {Card,} from '@douyinfe/semi-ui';
+import styled from "styled-components";
+import {useForm} from "antd/es/form/Form";
+import {ProForm, ProFormCheckbox, ProFormText, SubmitterProps} from 
"@ant-design/pro-components";
+import http from "@api/http.ts";
+import {API_ENDPOINTS} from "@api/endpoints.ts";
+import {Col, Row} from "antd";
+import "@douyinfe/semi-foundation/lib/es/button/button.css?inline"
+import {LoginParams} from "@src/types/User/data";
+
+
+const Login = () => {
+    // const dispatch = useDispatch();
+    // const navigate = useNavigate();
+
+    const [ldapEnabled, setLdapEnabled] = useState(false);
+    const [submitting, setSubmitting] = useState(false);
+
+    const [form] = useForm<LoginParams>();
+
+
+    useEffect(() => {
+        // todo: get ldap enabled status , the backend code is not ready yet
+        // http.httpGet(API_ENDPOINTS.GET_LDAP_ENABLE).then(res => {
+        //     setLdapEnabled(res.data);
+        //     form.setFieldValue("ldapLogin",res.data)
+        // }, err => console.error(err))
+    }, []);
+
+
+    const handleClickLogin = async () => {
+        setSubmitting(true);
+        const values = await form.validateFields();
+        await http.httpPost(API_ENDPOINTS.LOGIN, {...values}, () => 
setSubmitting(true), () => setSubmitting(false))
+    };
+
+    const proFormSubmitter: SubmitterProps = {
+        searchConfig: {submitText: 'Login'},
+        resetButtonProps: false,
+        submitButtonProps: {
+            className: "semi-button-primary",
+            type: 'primary',
+            loading: submitting,
+            autoFocus: true,
+            htmlType: 'submit',
+            size: "large",
+            shape: "round",
+            style: {
+                width: '100%',
+            }
+        },
+    };
+
+
+    return <Container>
+        <Card style={{width: 400}}>
+            <h3>Paimon Manager</h3>
+            <ProForm
+                form={form}
+                onFinish={handleClickLogin}
+                initialValues={{rememberMe: true}}
+                submitter={{...proFormSubmitter}}
+            >
+                <ProFormText
+                    name="username"
+                    label="Username"
+                    placeholder="Please input username"
+                    rules={[{required: true, message: 'Please input 
username'}]}
+                />
+                <ProFormText.Password
+                    name="password"
+                    label="Password"
+                    placeholder="Please input password"
+                    rules={[{required: true, message: 'Please input 
password'}]}
+                />
+                <Row>
+                    <Col span={18}>
+                        <ProFormCheckbox name="rememberMe">
+                            {/*{l("login.rememberMe")}*/} Remember Me
+                        </ProFormCheckbox>
+                    </Col>
+                    <Col span={6}>
+                        <ProFormCheckbox name="ldapLogin" 
hidden={!ldapEnabled}>
+                            {/*{l("login.ldapLogin")}*/} LDAP Login
+                        </ProFormCheckbox>
+                    </Col>
+                </Row>
+            </ProForm>
+        </Card>
+    </Container>
+}
+
+export default Login;
+
+const Container = styled.div`
+  background: 
url('https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/V-_oS6r-i7wAAAAAAAAAAAAAFl94AQBr')
 no-repeat;
+  background-size: 100% 100%;
+  height: 100vh;
+  overflow: hidden;
+  width: 100vw;
+  display: flex;
+  flex-direction: row;
+  flex-wrap: nowrap;
+  align-content: center;
+  justify-content: center;
+  align-items: center;
+  h3 {
+    font-size: 24px;
+    font-weight: 600;
+    text-align: center;
+    margin: 10px auto 20px;
+  }
+`
\ No newline at end of file
diff --git a/paimon-web-ui/src/router/index.tsx 
b/paimon-web-ui/src/router/index.tsx
index f481638..3a9af47 100644
--- a/paimon-web-ui/src/router/index.tsx
+++ b/paimon-web-ui/src/router/index.tsx
@@ -22,6 +22,7 @@ import LayoutPage from '@src/pages/Layout';
 import PlaygroundPage from '@src/pages/Playground';
 import MetaDataPage from '@pages/Metadata';
 import DevStatus from "@pages/Abnormal/Dev";
+import Login from "@pages/Other/Login";
 
 /*const Editor = lazy(() => import('@src/pages/Playground'))
 const Studio = lazy(() => import('@src/pages/Metadata'))*/
@@ -29,6 +30,10 @@ const Studio = lazy(() => import('@src/pages/Metadata'))*/
 const routeList: RouteObject[] = [
     {
         path: '/',
+        element: <Login/>,
+    },
+    {
+        path: '/layout',
         element: <LayoutPage/>,
         children: [
             {
@@ -44,6 +49,10 @@ const routeList: RouteObject[] = [
                 element: <DevStatus/>
             }
         ]
+    },
+    {
+        path: '*',
+        element: <Login/>
     }
 ]
 
diff --git a/paimon-web-ui/src/types/Public/data.d.ts 
b/paimon-web-ui/src/types/Public/data.d.ts
new file mode 100644
index 0000000..accfa53
--- /dev/null
+++ b/paimon-web-ui/src/types/Public/data.d.ts
@@ -0,0 +1,48 @@
+/*
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements.  See the NOTICE file distributed with
+ *   this work for additional information regarding copyright ownership.
+ *   The ASF licenses this file to You under the Apache License, Version 2.0
+ *   (the "License"); you may not use this file except in compliance with
+ *   the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+export interface Result<T> {
+    code: number;
+    msg: string;
+    data: T;
+}
+
+export interface PageData<T> {
+    records: T[];
+    page: number;
+    size: number;
+    total: number;
+}
+
+// with page
+export type PageResult<T> = Result<PageData<T>>
+
+
+
+
+export interface BaseBeanColumns extends ExcludeNameAndEnableColumns {
+    name: string,
+    enabled: boolean,
+}
+
+export interface ExcludeNameAndEnableColumns  {
+    id: number,
+    createTime: Date,
+    updateTime: Date,
+}
diff --git a/paimon-web-ui/src/types/User/data.d.ts 
b/paimon-web-ui/src/types/User/data.d.ts
new file mode 100644
index 0000000..1debcc2
--- /dev/null
+++ b/paimon-web-ui/src/types/User/data.d.ts
@@ -0,0 +1,104 @@
+/*
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements.  See the NOTICE file distributed with
+ *   this work for additional information regarding copyright ownership.
+ *   The ASF licenses this file to You under the Apache License, Version 2.0
+ *   (the "License"); you may not use this file except in compliance with
+ *   the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+import {BaseBeanColumns, ExcludeNameAndEnableColumns} from 
"@src/types/Public/data";
+
+/**
+ * user login params
+ */
+interface LoginParams {
+    username: string;
+    password: string;
+    rememberMe: boolean;
+    ldapLogin: boolean;
+}
+
+/**
+ * if login success, return user info and token
+ */
+export interface UserState {
+    status: boolean;
+    tokenInfo: SaTokenInfo;
+    roleList: Role[];
+    tenantList: Tenant[];
+    menuList: SysMenu[];
+    user: User;
+}
+
+
+/**
+ * user info
+ */
+export interface User extends ExcludeNameAndEnableColumns {
+    username: string;
+    nickname?: string;
+    password?: string;
+    avatar?: string;
+    worknum?: string;
+    userType: number;
+    mobile?: string;
+    enabled: boolean;
+    isDelete: boolean;
+}
+
+
+export interface SaTokenInfo  {
+    tokenName: string;
+    tokenValue: string;
+    isLogin: boolean;
+    loginId: number;
+    loginType: string;
+    tokenTimeout: number;
+    sessionTimeout: number;
+    tokenSessionTimeout: number;
+    tokenActivityTimeout: number;
+    loginDevice: string;
+    tag: string;
+}
+
+
+export interface Tenant extends ExcludeNameAndEnableColumns {
+    tenantCode: string;
+    isDelete: boolean;
+    note?: string;
+}
+
+export interface Role  extends ExcludeNameAndEnableColumns  {
+    tenantId: number;
+    tenant: Tenant;
+    roleCode?: string;
+    roleName?: string;
+    isDelete: boolean;
+    note?: string;
+}
+
+
+export interface SysMenu extends BaseBeanColumns  {
+    parentId: number, // 父级
+    orderNum: number, // 排序
+    path: string, // 路由
+    component: string, // 组件
+    type: string,// C菜单 F按钮 M目录
+    display: boolean, // 菜单状态(0显示 1隐藏)
+    perms: string, // 权限标识
+    icon: string, // 图标
+    rootMenu: boolean,
+    note: string,
+    children: SysMenu[],
+}
diff --git a/pom.xml b/pom.xml
index 028091e..93f1464 100644
--- a/pom.xml
+++ b/pom.xml
@@ -112,6 +112,7 @@ under the License.
         <mybatis-plus.version>3.5.3.1</mybatis-plus.version>
         <sa-token.version>1.35.0.RC</sa-token.version>
         <common-lang3.version>3.12.0</common-lang3.version>
+        <hutool.version>5.8.11</hutool.version>
     </properties>
 
     <dependencyManagement>
@@ -143,6 +144,12 @@ under the License.
                 <version>${guava.version}</version>
             </dependency>
 
+            <dependency>
+                <groupId>cn.hutool</groupId>
+                <artifactId>hutool-all</artifactId>
+                <version>${hutool.version}</version>
+            </dependency>
+
             <dependency>
                 <groupId>org.slf4j</groupId>
                 <artifactId>slf4j-api</artifactId>

Reply via email to