Full Code of bestaone/HiAuth for AI

master dba8e2850dee cached
2040 files
6.2 MB
1.8M tokens
2497 symbols
1 requests
Download .txt
Showing preview only (7,220K chars total). Download the full file or copy to clipboard to get everything.
Repository: bestaone/HiAuth
Branch: master
Commit: dba8e2850dee
Files: 2040
Total size: 6.2 MB

Directory structure:
gitextract_2zakr5hl/

├── .github/
│   └── workflows/
│       └── deploy.yml
├── .gitignore
├── LICENSE
├── README.md
├── cicd/
│   ├── Dockerfile
│   ├── Jenkinsfile
│   ├── hiauth.properties
│   └── nginx.conf
├── docs/
│   ├── .postcssrc.json
│   ├── .vitepress/
│   │   ├── config/
│   │   │   ├── en.ts
│   │   │   ├── index.ts
│   │   │   ├── shared.ts
│   │   │   └── zh.ts
│   │   └── theme/
│   │       ├── index.ts
│   │       └── styles.css
│   ├── en/
│   │   ├── guide/
│   │   │   ├── about-topic.md
│   │   │   ├── backend.md
│   │   │   ├── docker.md
│   │   │   ├── frontend.md
│   │   │   ├── hiauth-client.md
│   │   │   ├── issue.md
│   │   │   ├── k8s.md
│   │   │   ├── quick-start.md
│   │   │   ├── saas.md
│   │   │   ├── sourcecode.md
│   │   │   ├── test.md
│   │   │   └── what-is-hiauth.md
│   │   └── index.md
│   ├── lunaria.config.json
│   ├── package.json
│   ├── public/
│   │   ├── hiauth-logo-large.psd
│   │   └── pure.html
│   └── zh/
│       ├── guide/
│       │   ├── about-topic.md
│       │   ├── backend.md
│       │   ├── docker.md
│       │   ├── frontend.md
│       │   ├── hiauth-client.md
│       │   ├── issue.md
│       │   ├── k8s.md
│       │   ├── quick-start.md
│       │   ├── saas.md
│       │   ├── sourcecode.md
│       │   ├── test.md
│       │   └── what-is-hiauth.md
│       └── index.md
├── example/
│   ├── demo/
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── cn/
│   │           │       └── hiauth/
│   │           │           └── demo/
│   │           │               ├── DemoApplication.java
│   │           │               └── IndexController.java
│   │           └── resources/
│   │               └── application.yml
│   ├── hiauth-client/
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── cn/
│   │           │       └── hiauth/
│   │           │           └── hiauthclient/
│   │           │               ├── HiauthClientStarter.java
│   │           │               ├── config/
│   │           │               │   └── WebMvcConfig.java
│   │           │               └── controller/
│   │           │                   ├── ApiController.java
│   │           │                   └── IndexController.java
│   │           └── resources/
│   │               ├── application.yml
│   │               ├── logback.xml
│   │               ├── static/
│   │               │   └── css/
│   │               │       └── index.css
│   │               └── templates/
│   │                   ├── demo.html
│   │                   ├── index.html
│   │                   └── profile.html
│   ├── hiauth-client-exp/
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── cn/
│   │           │       └── hiauth/
│   │           │           └── client/
│   │           │               ├── ClientStarter.java
│   │           │               ├── config/
│   │           │               │   ├── BeanConfig.java
│   │           │               │   ├── SecurityConfig.java
│   │           │               │   └── WebMvcConfig.java
│   │           │               └── controller/
│   │           │                   └── ClientController.java
│   │           └── resources/
│   │               ├── application.yml
│   │               ├── logback.xml
│   │               └── templates/
│   │                   └── index.html
│   ├── hiauth-server-exp/
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── cn/
│   │           │       └── hiauth/
│   │           │           └── server/
│   │           │               ├── ServerStarter.java
│   │           │               ├── config/
│   │           │               │   ├── AuthServerConfig.java
│   │           │               │   ├── BeanConfig.java
│   │           │               │   ├── SecurityConfig.java
│   │           │               │   └── WebMvcConfig.java
│   │           │               ├── controller/
│   │           │               │   ├── IndexController.java
│   │           │               │   └── LoginController.java
│   │           │               ├── federation/
│   │           │               │   ├── FederatedIdentityAuthenticationSuccessHandler.java
│   │           │               │   └── FederatedIdentityIdTokenCustomizer.java
│   │           │               ├── mapper/
│   │           │               │   └── SimpleJdbcRegisteredClientRepository.java
│   │           │               └── utils/
│   │           │                   ├── jose/
│   │           │                   │   ├── Jwks.java
│   │           │                   │   └── KeyGeneratorUtils.java
│   │           │                   └── package-info.java
│   │           └── resources/
│   │               ├── application-hiauth.yml
│   │               ├── application-redis.yml
│   │               ├── application.yml
│   │               ├── logback.xml
│   │               └── templates/
│   │                   └── index.html
│   ├── himall/
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── cn/
│   │           │       └── hiauth/
│   │           │           └── himall/
│   │           │               ├── HiMallStarter.java
│   │           │               ├── config/
│   │           │               │   ├── SecurityConfig.java
│   │           │               │   └── WebMvcConfig.java
│   │           │               └── controller/
│   │           │                   ├── AuthController.java
│   │           │                   └── IndexController.java
│   │           └── resources/
│   │               ├── application.yml
│   │               ├── logback.xml
│   │               ├── static/
│   │               │   └── css/
│   │               │       └── index.css
│   │               └── templates/
│   │                   ├── demo.html
│   │                   ├── index.html
│   │                   └── profile.html
│   ├── resource/
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── cn/
│   │           │       └── hiauth/
│   │           │           └── resource/
│   │           │               ├── ResourceStarter.java
│   │           │               ├── config/
│   │           │               │   ├── ResourceServerConfig.java
│   │           │               │   └── auth/
│   │           │               │       ├── SimpleAccessDeniedHandler.java
│   │           │               │       └── SimpleAuthenticationEntryPoint.java
│   │           │               ├── controller/
│   │           │               │   ├── IndexController.java
│   │           │               │   ├── ProfileController.java
│   │           │               │   ├── UnpapiController.java
│   │           │               │   └── UserController.java
│   │           │               └── utils/
│   │           │                   └── ResponseTools.java
│   │           └── resources/
│   │               ├── application.yml
│   │               └── logback.xml
│   ├── spring-cloud/
│   │   ├── README.md
│   │   ├── gateway/
│   │   │   ├── pom.xml
│   │   │   └── src/
│   │   │       └── main/
│   │   │           ├── java/
│   │   │           │   └── cn/
│   │   │           │       └── hiauth/
│   │   │           │           └── gateway/
│   │   │           │               ├── ApiController.java
│   │   │           │               ├── GatewayStarter.java
│   │   │           │               ├── IndexController.java
│   │   │           │               └── SecurityConfig.java
│   │   │           └── resources/
│   │   │               ├── application.yml
│   │   │               └── logback.xml
│   │   ├── ordersvc/
│   │   │   ├── pom.xml
│   │   │   └── src/
│   │   │       └── main/
│   │   │           ├── java/
│   │   │           │   └── cn/
│   │   │           │       └── hiauth/
│   │   │           │           └── gateway/
│   │   │           │               ├── IndexController.java
│   │   │           │               └── OrderStarter.java
│   │   │           └── resources/
│   │   │               ├── application.yml
│   │   │               └── logback.xml
│   │   └── pom.xml
│   ├── spring-cloud-with-hiauth-client/
│   │   ├── README.md
│   │   ├── gateway1/
│   │   │   ├── pom.xml
│   │   │   └── src/
│   │   │       └── main/
│   │   │           ├── java/
│   │   │           │   └── cn/
│   │   │           │       └── hiauth/
│   │   │           │           └── gateway/
│   │   │           │               ├── ApiController.java
│   │   │           │               ├── GatewayStarter.java
│   │   │           │               └── IndexController.java
│   │   │           └── resources/
│   │   │               ├── application.yml
│   │   │               └── logback.xml
│   │   ├── ordersvc1/
│   │   │   ├── pom.xml
│   │   │   └── src/
│   │   │       └── main/
│   │   │           ├── java/
│   │   │           │   └── cn/
│   │   │           │       └── hiauth/
│   │   │           │           └── gateway/
│   │   │           │               ├── IndexController.java
│   │   │           │               └── OrderStarter.java
│   │   │           └── resources/
│   │   │               ├── application.yml
│   │   │               └── logback.xml
│   │   └── pom.xml
│   └── wechat-login/
│       ├── pom.xml
│       └── src/
│           └── main/
│               ├── java/
│               │   └── cn/
│               │       └── hiauth/
│               │           └── wechatlogin/
│               │               ├── WechatLoginStarter.java
│               │               ├── config/
│               │               │   ├── SecurityConfig.java
│               │               │   ├── WebMvcConfig.java
│               │               │   └── web/
│               │               │       ├── auth/
│               │               │       │   └── package-info.java
│               │               │       └── security/
│               │               │           ├── phone/
│               │               │           │   ├── SmsCodeAuthenticationFilter.java
│               │               │           │   ├── SmsCodeAuthenticationProvider.java
│               │               │           │   └── SmsCodeAuthenticationToken.java
│               │               │           └── wechat/
│               │               │               ├── QrCodeAuthenticationFilter.java
│               │               │               ├── QrCodeAuthenticationProvider.java
│               │               │               └── QrCodeAuthenticationToken.java
│               │               ├── controller/
│               │               │   ├── AuthController.java
│               │               │   └── IndexController.java
│               │               ├── entity/
│               │               │   └── CustomUserDetails.java
│               │               └── service/
│               │                   └── CustomUserDetailsService.java
│               └── resources/
│                   ├── application.yml
│                   ├── logback.xml
│                   └── templates/
│                       ├── home.html
│                       ├── index.html
│                       └── login.html
├── hiauth-client-starter/
│   ├── hiauth-client-commons/
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── cn/
│   │                   └── hiauth/
│   │                       └── client/
│   │                           ├── Authentication.java
│   │                           ├── Client.java
│   │                           ├── Constant.java
│   │                           ├── HiAuthToken.java
│   │                           ├── JwtUtils.java
│   │                           ├── SecurityCorp.java
│   │                           ├── SecurityService.java
│   │                           ├── SecurityUser.java
│   │                           ├── SessionContext.java
│   │                           ├── SessionContextHolder.java
│   │                           ├── TokenVo.java
│   │                           └── UserinfoVo.java
│   ├── hiauth-client-resource-spring-boot-starter/
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── cn/
│   │           │       └── hiauth/
│   │           │           └── client/
│   │           │               └── resource/
│   │           │                   ├── HiAuthClientResourceAutoConfig.java
│   │           │                   └── HiAuthClientResourceProperties.java
│   │           └── resources/
│   │               └── META-INF/
│   │                   ├── spring-configuration-metadata.json
│   │                   └── spring.factories
│   ├── hiauth-client-session-spring-boot-starter/
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── cn/
│   │           │       └── hiauth/
│   │           │           └── client/
│   │           │               └── session/
│   │           │                   ├── AuthFilter.java
│   │           │                   ├── HiAuthClientSessionAutoConfig.java
│   │           │                   ├── HiAuthClientSessionCacheConfig.java
│   │           │                   ├── HiAuthClientSessionController.java
│   │           │                   ├── HiAuthClientSessionProperties.java
│   │           │                   └── HiAuthClientSessionRunner.java
│   │           └── resources/
│   │               └── META-INF/
│   │                   ├── spring-configuration-metadata.json
│   │                   └── spring.factories
│   ├── hiauth-client-spring-boot-starter/
│   │   ├── docs/
│   │   │   └── apisvc-oms.yml
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── cn/
│   │           │       └── hiauth/
│   │           │           └── client/
│   │           │               ├── AuthFilter.java
│   │           │               ├── HiAuthCacheConfig.java
│   │           │               ├── HiAuthClientAutoConfig.java
│   │           │               ├── HiAuthClientController.java
│   │           │               ├── HiAuthClientProperties.java
│   │           │               ├── HiAuthClientProviderProperties.java
│   │           │               ├── HiAuthClientRegistrationProperties.java
│   │           │               ├── HiAuthClientRunner.java
│   │           │               └── api/
│   │           │                   ├── TokenVo.java
│   │           │                   └── UserPwdUpdateDto.java
│   │           └── resources/
│   │               └── META-INF/
│   │                   ├── spring-configuration-metadata.json
│   │                   └── spring.factories
│   ├── hiauth-client-spring-cloud-gateway-starter/
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── cn/
│   │           │       └── hiauth/
│   │           │           └── client/
│   │           │               └── gateway/
│   │           │                   ├── AuthGatewayFilterFactory.java
│   │           │                   ├── HiAuthClientGatewayAutoConfig.java
│   │           │                   ├── HiAuthClientGatewayController.java
│   │           │                   ├── HiAuthClientGatewayProperties.java
│   │           │                   ├── HiAuthClientGatewayRunner.java
│   │           │                   └── UserPwdUpdateDto.java
│   │           └── resources/
│   │               └── META-INF/
│   │                   ├── spring-configuration-metadata.json
│   │                   └── spring.factories
│   └── pom.xml
├── hiauth-front/
│   ├── .browserslistrc
│   ├── .changeset/
│   │   ├── README.md
│   │   └── config.json
│   ├── .commitlintrc.js
│   ├── .dockerignore
│   ├── .editorconfig
│   ├── .gitattributes
│   ├── .gitconfig
│   ├── .gitignore
│   ├── .gitpod.yml
│   ├── .node-version
│   ├── .npmrc
│   ├── .prettierignore
│   ├── .prettierrc.mjs
│   ├── .stylelintignore
│   ├── Dockerfile
│   ├── LICENSE
│   ├── README.ja-JP.md
│   ├── README.md
│   ├── README.zh-CN.md
│   ├── apps/
│   │   ├── backend-mock/
│   │   │   ├── README.md
│   │   │   ├── api/
│   │   │   │   ├── auth/
│   │   │   │   │   ├── codes.ts
│   │   │   │   │   ├── login.post.ts
│   │   │   │   │   ├── logout.post.ts
│   │   │   │   │   └── refresh.post.ts
│   │   │   │   ├── demo/
│   │   │   │   │   └── bigint.ts
│   │   │   │   ├── menu/
│   │   │   │   │   └── all.ts
│   │   │   │   ├── status.ts
│   │   │   │   ├── system/
│   │   │   │   │   ├── dept/
│   │   │   │   │   │   ├── .post.ts
│   │   │   │   │   │   ├── [id].delete.ts
│   │   │   │   │   │   ├── [id].put.ts
│   │   │   │   │   │   └── list.ts
│   │   │   │   │   ├── menu/
│   │   │   │   │   │   ├── list.ts
│   │   │   │   │   │   ├── name-exists.ts
│   │   │   │   │   │   └── path-exists.ts
│   │   │   │   │   └── role/
│   │   │   │   │       └── list.ts
│   │   │   │   ├── table/
│   │   │   │   │   └── list.ts
│   │   │   │   ├── test.get.ts
│   │   │   │   ├── test.post.ts
│   │   │   │   ├── upload.ts
│   │   │   │   └── user/
│   │   │   │       └── info.ts
│   │   │   ├── error.ts
│   │   │   ├── middleware/
│   │   │   │   └── 1.api.ts
│   │   │   ├── nitro.config.ts
│   │   │   ├── package.json
│   │   │   ├── routes/
│   │   │   │   └── [...].ts
│   │   │   ├── tsconfig.build.json
│   │   │   ├── tsconfig.json
│   │   │   └── utils/
│   │   │       ├── cookie-utils.ts
│   │   │       ├── jwt-utils.ts
│   │   │       ├── mock-data.ts
│   │   │       └── response.ts
│   │   ├── web-antd/
│   │   │   ├── index.html
│   │   │   ├── package.json
│   │   │   ├── postcss.config.mjs
│   │   │   ├── src/
│   │   │   │   ├── adapter/
│   │   │   │   │   ├── component/
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── form.ts
│   │   │   │   │   └── vxe-table.ts
│   │   │   │   ├── api/
│   │   │   │   │   ├── core/
│   │   │   │   │   │   ├── auth.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── menu.ts
│   │   │   │   │   │   └── user.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── request.ts
│   │   │   │   ├── app.vue
│   │   │   │   ├── bootstrap.ts
│   │   │   │   ├── layouts/
│   │   │   │   │   ├── auth.vue
│   │   │   │   │   ├── basic.vue
│   │   │   │   │   └── index.ts
│   │   │   │   ├── locales/
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── langs/
│   │   │   │   │       ├── en-US/
│   │   │   │   │       │   ├── demos.json
│   │   │   │   │       │   └── page.json
│   │   │   │   │       └── zh-CN/
│   │   │   │   │           ├── demos.json
│   │   │   │   │           └── page.json
│   │   │   │   ├── main.ts
│   │   │   │   ├── preferences.ts
│   │   │   │   ├── router/
│   │   │   │   │   ├── access.ts
│   │   │   │   │   ├── guard.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── routes/
│   │   │   │   │       ├── core.ts
│   │   │   │   │       ├── index.ts
│   │   │   │   │       └── modules/
│   │   │   │   │           ├── dashboard.ts
│   │   │   │   │           ├── demos.ts
│   │   │   │   │           └── vben.ts
│   │   │   │   ├── store/
│   │   │   │   │   ├── auth.ts
│   │   │   │   │   └── index.ts
│   │   │   │   └── views/
│   │   │   │       ├── _core/
│   │   │   │       │   ├── README.md
│   │   │   │       │   ├── about/
│   │   │   │       │   │   └── index.vue
│   │   │   │       │   ├── authentication/
│   │   │   │       │   │   ├── code-login.vue
│   │   │   │       │   │   ├── forget-password.vue
│   │   │   │       │   │   ├── login.vue
│   │   │   │       │   │   ├── qrcode-login.vue
│   │   │   │       │   │   └── register.vue
│   │   │   │       │   └── fallback/
│   │   │   │       │       ├── coming-soon.vue
│   │   │   │       │       ├── forbidden.vue
│   │   │   │       │       ├── internal-error.vue
│   │   │   │       │       ├── not-found.vue
│   │   │   │       │       └── offline.vue
│   │   │   │       ├── dashboard/
│   │   │   │       │   ├── analytics/
│   │   │   │       │   │   ├── analytics-trends.vue
│   │   │   │       │   │   ├── analytics-visits-data.vue
│   │   │   │       │   │   ├── analytics-visits-sales.vue
│   │   │   │       │   │   ├── analytics-visits-source.vue
│   │   │   │       │   │   ├── analytics-visits.vue
│   │   │   │       │   │   └── index.vue
│   │   │   │       │   └── workspace/
│   │   │   │       │       └── index.vue
│   │   │   │       └── demos/
│   │   │   │           └── antd/
│   │   │   │               └── index.vue
│   │   │   ├── tailwind.config.mjs
│   │   │   ├── tsconfig.json
│   │   │   ├── tsconfig.node.json
│   │   │   └── vite.config.mts
│   │   ├── web-auth/
│   │   │   ├── index.html
│   │   │   ├── package.json
│   │   │   ├── postcss.config.mjs
│   │   │   ├── src/
│   │   │   │   ├── adapter/
│   │   │   │   │   ├── component/
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── form.ts
│   │   │   │   │   └── vxe-table.ts
│   │   │   │   ├── api/
│   │   │   │   │   ├── core/
│   │   │   │   │   │   ├── app.ts
│   │   │   │   │   │   ├── appClient.ts
│   │   │   │   │   │   ├── appResource.ts
│   │   │   │   │   │   ├── auth.ts
│   │   │   │   │   │   ├── common.ts
│   │   │   │   │   │   ├── corp.ts
│   │   │   │   │   │   ├── dep.ts
│   │   │   │   │   │   ├── dict.ts
│   │   │   │   │   │   ├── emp.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── menu.ts
│   │   │   │   │   │   ├── role.ts
│   │   │   │   │   │   └── user.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── request.ts
│   │   │   │   ├── app.vue
│   │   │   │   ├── bootstrap.ts
│   │   │   │   ├── common/
│   │   │   │   │   ├── config.ts
│   │   │   │   │   ├── constants.ts
│   │   │   │   │   ├── context.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── types.ts
│   │   │   │   ├── layouts/
│   │   │   │   │   ├── auth.vue
│   │   │   │   │   ├── basic.vue
│   │   │   │   │   ├── change-corp.vue
│   │   │   │   │   ├── go-admin-space-button.vue
│   │   │   │   │   └── index.ts
│   │   │   │   ├── locales/
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── langs/
│   │   │   │   │       ├── en-US/
│   │   │   │   │       │   ├── demos.json
│   │   │   │   │       │   └── page.json
│   │   │   │   │       └── zh-CN/
│   │   │   │   │           ├── demos.json
│   │   │   │   │           └── page.json
│   │   │   │   ├── main.ts
│   │   │   │   ├── preferences.ts
│   │   │   │   ├── router/
│   │   │   │   │   ├── access.ts
│   │   │   │   │   ├── guard.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── routes/
│   │   │   │   │       ├── core.ts
│   │   │   │   │       ├── index.ts
│   │   │   │   │       └── modules/
│   │   │   │   │           ├── adminSpace.ts
│   │   │   │   │           ├── common.ts
│   │   │   │   │           ├── corpSpace.ts
│   │   │   │   │           └── dashboard.ts
│   │   │   │   ├── store/
│   │   │   │   │   ├── auth.ts
│   │   │   │   │   ├── content.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── utils/
│   │   │   │   │   └── rsa.ts
│   │   │   │   └── views/
│   │   │   │       ├── _core/
│   │   │   │       │   ├── README.md
│   │   │   │       │   ├── about/
│   │   │   │       │   │   └── index.vue
│   │   │   │       │   ├── authentication/
│   │   │   │       │   │   ├── code-login.vue
│   │   │   │       │   │   ├── forget-password.vue
│   │   │   │       │   │   ├── login.vue
│   │   │   │       │   │   ├── qrcode-login.vue
│   │   │   │       │   │   └── register.vue
│   │   │   │       │   └── fallback/
│   │   │   │       │       ├── coming-soon.vue
│   │   │   │       │       ├── forbidden.vue
│   │   │   │       │       ├── internal-error.vue
│   │   │   │       │       ├── not-found.vue
│   │   │   │       │       └── offline.vue
│   │   │   │       ├── adminSpace/
│   │   │   │       │   ├── corpMgr/
│   │   │   │       │   │   ├── corp-drawer.vue
│   │   │   │       │   │   └── index.vue
│   │   │   │       │   └── userMgr/
│   │   │   │       │       ├── index.vue
│   │   │   │       │       └── user-drawer.vue
│   │   │   │       ├── common/
│   │   │   │       │   ├── appMgr/
│   │   │   │       │   │   ├── app-drawer.vue
│   │   │   │       │   │   └── index.vue
│   │   │   │       │   └── appResourceMgr/
│   │   │   │       │       ├── app-resource-drawer.vue
│   │   │   │       │       └── index.vue
│   │   │   │       ├── corpSpace/
│   │   │   │       │   ├── appClientMgr/
│   │   │   │       │   │   ├── app-client-add-modal.vue
│   │   │   │       │   │   ├── app-client-drawer.vue
│   │   │   │       │   │   └── index.vue
│   │   │   │       │   ├── depMgr/
│   │   │   │       │   │   ├── dep-drawer.vue
│   │   │   │       │   │   └── index.vue
│   │   │   │       │   ├── empMgr/
│   │   │   │       │   │   ├── emp-drawer.vue
│   │   │   │       │   │   └── index.vue
│   │   │   │       │   ├── roleMgr/
│   │   │   │       │   │   ├── auth-modal.vue
│   │   │   │       │   │   ├── index.vue
│   │   │   │       │   │   └── role-drawer.vue
│   │   │   │       │   └── sysMgr/
│   │   │   │       │       └── dictMgr/
│   │   │   │       │           ├── dict-drawer.vue
│   │   │   │       │           └── index.vue
│   │   │   │       ├── dashboard/
│   │   │   │       │   ├── analytics/
│   │   │   │       │   │   ├── analytics-trends.vue
│   │   │   │       │   │   ├── analytics-visits-data.vue
│   │   │   │       │   │   ├── analytics-visits-sales.vue
│   │   │   │       │   │   ├── analytics-visits-source.vue
│   │   │   │       │   │   ├── analytics-visits.vue
│   │   │   │       │   │   └── index.vue
│   │   │   │       │   └── workspace/
│   │   │   │       │       └── index.vue
│   │   │   │       └── demos/
│   │   │   │           └── antd/
│   │   │   │               └── index.vue
│   │   │   ├── tailwind.config.mjs
│   │   │   ├── tsconfig.json
│   │   │   ├── tsconfig.node.json
│   │   │   └── vite.config.mts
│   │   ├── web-ele/
│   │   │   ├── index.html
│   │   │   ├── package.json
│   │   │   ├── postcss.config.mjs
│   │   │   ├── src/
│   │   │   │   ├── adapter/
│   │   │   │   │   ├── component/
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── form.ts
│   │   │   │   │   └── vxe-table.ts
│   │   │   │   ├── api/
│   │   │   │   │   ├── core/
│   │   │   │   │   │   ├── auth.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── menu.ts
│   │   │   │   │   │   └── user.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── request.ts
│   │   │   │   ├── app.vue
│   │   │   │   ├── bootstrap.ts
│   │   │   │   ├── layouts/
│   │   │   │   │   ├── auth.vue
│   │   │   │   │   ├── basic.vue
│   │   │   │   │   └── index.ts
│   │   │   │   ├── locales/
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── langs/
│   │   │   │   │       ├── en-US/
│   │   │   │   │       │   ├── demos.json
│   │   │   │   │       │   └── page.json
│   │   │   │   │       └── zh-CN/
│   │   │   │   │           ├── demos.json
│   │   │   │   │           └── page.json
│   │   │   │   ├── main.ts
│   │   │   │   ├── preferences.ts
│   │   │   │   ├── router/
│   │   │   │   │   ├── access.ts
│   │   │   │   │   ├── guard.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── routes/
│   │   │   │   │       ├── core.ts
│   │   │   │   │       ├── index.ts
│   │   │   │   │       └── modules/
│   │   │   │   │           ├── dashboard.ts
│   │   │   │   │           ├── demos.ts
│   │   │   │   │           └── vben.ts
│   │   │   │   ├── store/
│   │   │   │   │   ├── auth.ts
│   │   │   │   │   └── index.ts
│   │   │   │   └── views/
│   │   │   │       ├── _core/
│   │   │   │       │   ├── README.md
│   │   │   │       │   ├── about/
│   │   │   │       │   │   └── index.vue
│   │   │   │       │   ├── authentication/
│   │   │   │       │   │   ├── code-login.vue
│   │   │   │       │   │   ├── forget-password.vue
│   │   │   │       │   │   ├── login.vue
│   │   │   │       │   │   ├── qrcode-login.vue
│   │   │   │       │   │   └── register.vue
│   │   │   │       │   └── fallback/
│   │   │   │       │       ├── coming-soon.vue
│   │   │   │       │       ├── forbidden.vue
│   │   │   │       │       ├── internal-error.vue
│   │   │   │       │       ├── not-found.vue
│   │   │   │       │       └── offline.vue
│   │   │   │       ├── dashboard/
│   │   │   │       │   ├── analytics/
│   │   │   │       │   │   ├── analytics-trends.vue
│   │   │   │       │   │   ├── analytics-visits-data.vue
│   │   │   │       │   │   ├── analytics-visits-sales.vue
│   │   │   │       │   │   ├── analytics-visits-source.vue
│   │   │   │       │   │   ├── analytics-visits.vue
│   │   │   │       │   │   └── index.vue
│   │   │   │       │   └── workspace/
│   │   │   │       │       └── index.vue
│   │   │   │       └── demos/
│   │   │   │           ├── element/
│   │   │   │           │   └── index.vue
│   │   │   │           └── form/
│   │   │   │               └── basic.vue
│   │   │   ├── tailwind.config.mjs
│   │   │   ├── tsconfig.json
│   │   │   ├── tsconfig.node.json
│   │   │   └── vite.config.mts
│   │   └── web-naive/
│   │       ├── index.html
│   │       ├── package.json
│   │       ├── postcss.config.mjs
│   │       ├── src/
│   │       │   ├── adapter/
│   │       │   │   ├── component/
│   │       │   │   │   └── index.ts
│   │       │   │   ├── form.ts
│   │       │   │   ├── naive.ts
│   │       │   │   └── vxe-table.ts
│   │       │   ├── api/
│   │       │   │   ├── core/
│   │       │   │   │   ├── auth.ts
│   │       │   │   │   ├── index.ts
│   │       │   │   │   ├── menu.ts
│   │       │   │   │   └── user.ts
│   │       │   │   ├── index.ts
│   │       │   │   └── request.ts
│   │       │   ├── app.vue
│   │       │   ├── bootstrap.ts
│   │       │   ├── layouts/
│   │       │   │   ├── auth.vue
│   │       │   │   ├── basic.vue
│   │       │   │   └── index.ts
│   │       │   ├── locales/
│   │       │   │   ├── README.md
│   │       │   │   ├── index.ts
│   │       │   │   └── langs/
│   │       │   │       ├── en-US/
│   │       │   │       │   ├── demos.json
│   │       │   │       │   └── page.json
│   │       │   │       └── zh-CN/
│   │       │   │           ├── demos.json
│   │       │   │           └── page.json
│   │       │   ├── main.ts
│   │       │   ├── preferences.ts
│   │       │   ├── router/
│   │       │   │   ├── access.ts
│   │       │   │   ├── guard.ts
│   │       │   │   ├── index.ts
│   │       │   │   └── routes/
│   │       │   │       ├── core.ts
│   │       │   │       ├── index.ts
│   │       │   │       └── modules/
│   │       │   │           ├── dashboard.ts
│   │       │   │           ├── demos.ts
│   │       │   │           └── vben.ts
│   │       │   ├── store/
│   │       │   │   ├── auth.ts
│   │       │   │   └── index.ts
│   │       │   └── views/
│   │       │       ├── _core/
│   │       │       │   ├── README.md
│   │       │       │   ├── about/
│   │       │       │   │   └── index.vue
│   │       │       │   ├── authentication/
│   │       │       │   │   ├── code-login.vue
│   │       │       │   │   ├── forget-password.vue
│   │       │       │   │   ├── login.vue
│   │       │       │   │   ├── qrcode-login.vue
│   │       │       │   │   └── register.vue
│   │       │       │   └── fallback/
│   │       │       │       ├── coming-soon.vue
│   │       │       │       ├── forbidden.vue
│   │       │       │       ├── internal-error.vue
│   │       │       │       ├── not-found.vue
│   │       │       │       └── offline.vue
│   │       │       ├── dashboard/
│   │       │       │   ├── analytics/
│   │       │       │   │   ├── analytics-trends.vue
│   │       │       │   │   ├── analytics-visits-data.vue
│   │       │       │   │   ├── analytics-visits-sales.vue
│   │       │       │   │   ├── analytics-visits-source.vue
│   │       │       │   │   ├── analytics-visits.vue
│   │       │       │   │   └── index.vue
│   │       │       │   └── workspace/
│   │       │       │       └── index.vue
│   │       │       └── demos/
│   │       │           ├── form/
│   │       │           │   ├── basic.vue
│   │       │           │   └── modal.vue
│   │       │           ├── naive/
│   │       │           │   └── index.vue
│   │       │           └── table/
│   │       │               └── index.vue
│   │       ├── tailwind.config.mjs
│   │       ├── tsconfig.json
│   │       ├── tsconfig.node.json
│   │       └── vite.config.mts
│   ├── changlist.txt
│   ├── cspell.json
│   ├── deploy.yaml
│   ├── docs/
│   │   ├── .vitepress/
│   │   │   ├── components/
│   │   │   │   ├── demo-preview.vue
│   │   │   │   ├── index.ts
│   │   │   │   └── preview-group.vue
│   │   │   ├── config/
│   │   │   │   ├── en.mts
│   │   │   │   ├── index.mts
│   │   │   │   ├── plugins/
│   │   │   │   │   └── demo-preview.ts
│   │   │   │   ├── shared.mts
│   │   │   │   └── zh.mts
│   │   │   └── theme/
│   │   │       ├── components/
│   │   │       │   ├── site-layout.vue
│   │   │       │   └── vben-contributors.vue
│   │   │       ├── index.ts
│   │   │       ├── plugins/
│   │   │       │   └── hm.ts
│   │   │       └── styles/
│   │   │           ├── base.css
│   │   │           ├── index.ts
│   │   │           └── variables.css
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── _env/
│   │   │   │   ├── adapter/
│   │   │   │   │   ├── component.ts
│   │   │   │   │   ├── form.ts
│   │   │   │   │   └── vxe-table.ts
│   │   │   │   └── node/
│   │   │   │       └── adapter/
│   │   │   │           ├── form.ts
│   │   │   │           └── vxe-table.ts
│   │   │   ├── commercial/
│   │   │   │   ├── community.md
│   │   │   │   ├── customized.md
│   │   │   │   └── technical-support.md
│   │   │   ├── components/
│   │   │   │   ├── common-ui/
│   │   │   │   │   ├── vben-alert.md
│   │   │   │   │   ├── vben-api-component.md
│   │   │   │   │   ├── vben-count-to-animator.md
│   │   │   │   │   ├── vben-drawer.md
│   │   │   │   │   ├── vben-ellipsis-text.md
│   │   │   │   │   ├── vben-form.md
│   │   │   │   │   ├── vben-modal.md
│   │   │   │   │   └── vben-vxe-table.md
│   │   │   │   ├── introduction.md
│   │   │   │   └── layout-ui/
│   │   │   │       └── page.md
│   │   │   ├── demos/
│   │   │   │   ├── vben-alert/
│   │   │   │   │   ├── alert/
│   │   │   │   │   │   └── index.vue
│   │   │   │   │   ├── confirm/
│   │   │   │   │   │   └── index.vue
│   │   │   │   │   └── prompt/
│   │   │   │   │       └── index.vue
│   │   │   │   ├── vben-api-component/
│   │   │   │   │   └── cascader/
│   │   │   │   │       └── index.vue
│   │   │   │   ├── vben-count-to-animator/
│   │   │   │   │   ├── basic/
│   │   │   │   │   │   └── index.vue
│   │   │   │   │   └── custom/
│   │   │   │   │       └── index.vue
│   │   │   │   ├── vben-drawer/
│   │   │   │   │   ├── auto-height/
│   │   │   │   │   │   ├── drawer.vue
│   │   │   │   │   │   └── index.vue
│   │   │   │   │   ├── basic/
│   │   │   │   │   │   └── index.vue
│   │   │   │   │   ├── dynamic/
│   │   │   │   │   │   ├── drawer.vue
│   │   │   │   │   │   └── index.vue
│   │   │   │   │   ├── extra/
│   │   │   │   │   │   ├── drawer.vue
│   │   │   │   │   │   └── index.vue
│   │   │   │   │   └── shared-data/
│   │   │   │   │       ├── drawer.vue
│   │   │   │   │       └── index.vue
│   │   │   │   ├── vben-ellipsis-text/
│   │   │   │   │   ├── auto-display/
│   │   │   │   │   │   └── index.vue
│   │   │   │   │   ├── expand/
│   │   │   │   │   │   └── index.vue
│   │   │   │   │   ├── line/
│   │   │   │   │   │   └── index.vue
│   │   │   │   │   └── tooltip/
│   │   │   │   │       └── index.vue
│   │   │   │   ├── vben-form/
│   │   │   │   │   ├── api/
│   │   │   │   │   │   └── index.vue
│   │   │   │   │   ├── basic/
│   │   │   │   │   │   └── index.vue
│   │   │   │   │   ├── custom/
│   │   │   │   │   │   └── index.vue
│   │   │   │   │   ├── dynamic/
│   │   │   │   │   │   └── index.vue
│   │   │   │   │   ├── query/
│   │   │   │   │   │   └── index.vue
│   │   │   │   │   └── rules/
│   │   │   │   │       └── index.vue
│   │   │   │   ├── vben-modal/
│   │   │   │   │   ├── animation-type/
│   │   │   │   │   │   └── index.vue
│   │   │   │   │   ├── auto-height/
│   │   │   │   │   │   ├── index.vue
│   │   │   │   │   │   └── modal.vue
│   │   │   │   │   ├── basic/
│   │   │   │   │   │   └── index.vue
│   │   │   │   │   ├── draggable/
│   │   │   │   │   │   ├── index.vue
│   │   │   │   │   │   └── modal.vue
│   │   │   │   │   ├── dynamic/
│   │   │   │   │   │   ├── index.vue
│   │   │   │   │   │   └── modal.vue
│   │   │   │   │   ├── extra/
│   │   │   │   │   │   ├── index.vue
│   │   │   │   │   │   └── modal.vue
│   │   │   │   │   └── shared-data/
│   │   │   │   │       ├── index.vue
│   │   │   │   │       └── modal.vue
│   │   │   │   └── vben-vxe-table/
│   │   │   │       ├── basic/
│   │   │   │       │   └── index.vue
│   │   │   │       ├── custom-cell/
│   │   │   │       │   └── index.vue
│   │   │   │       ├── edit-cell/
│   │   │   │       │   └── index.vue
│   │   │   │       ├── edit-row/
│   │   │   │       │   └── index.vue
│   │   │   │       ├── fixed/
│   │   │   │       │   └── index.vue
│   │   │   │       ├── form/
│   │   │   │       │   └── index.vue
│   │   │   │       ├── mock-api.ts
│   │   │   │       ├── remote/
│   │   │   │       │   └── index.vue
│   │   │   │       ├── table-data.ts
│   │   │   │       ├── tree/
│   │   │   │       │   └── index.vue
│   │   │   │       └── virtual/
│   │   │   │           └── index.vue
│   │   │   ├── en/
│   │   │   │   ├── guide/
│   │   │   │   │   ├── essentials/
│   │   │   │   │   │   ├── build.md
│   │   │   │   │   │   ├── concept.md
│   │   │   │   │   │   ├── development.md
│   │   │   │   │   │   ├── external-module.md
│   │   │   │   │   │   ├── icons.md
│   │   │   │   │   │   ├── route.md
│   │   │   │   │   │   ├── server.md
│   │   │   │   │   │   ├── settings.md
│   │   │   │   │   │   └── styles.md
│   │   │   │   │   ├── in-depth/
│   │   │   │   │   │   ├── access.md
│   │   │   │   │   │   ├── check-updates.md
│   │   │   │   │   │   ├── features.md
│   │   │   │   │   │   ├── layout.md
│   │   │   │   │   │   ├── loading.md
│   │   │   │   │   │   ├── locale.md
│   │   │   │   │   │   ├── login.md
│   │   │   │   │   │   ├── theme.md
│   │   │   │   │   │   └── ui-framework.md
│   │   │   │   │   ├── introduction/
│   │   │   │   │   │   ├── changelog.md
│   │   │   │   │   │   ├── quick-start.md
│   │   │   │   │   │   ├── roadmap.md
│   │   │   │   │   │   ├── thin.md
│   │   │   │   │   │   ├── vben.md
│   │   │   │   │   │   └── why.md
│   │   │   │   │   ├── other/
│   │   │   │   │   │   ├── faq.md
│   │   │   │   │   │   ├── project-update.md
│   │   │   │   │   │   └── remove-code.md
│   │   │   │   │   └── project/
│   │   │   │   │       ├── changeset.md
│   │   │   │   │       ├── cli.md
│   │   │   │   │       ├── dir.md
│   │   │   │   │       ├── standard.md
│   │   │   │   │       ├── tailwindcss.md
│   │   │   │   │       ├── test.md
│   │   │   │   │       └── vite.md
│   │   │   │   └── index.md
│   │   │   ├── friend-links/
│   │   │   │   └── index.md
│   │   │   ├── guide/
│   │   │   │   ├── essentials/
│   │   │   │   │   ├── build.md
│   │   │   │   │   ├── concept.md
│   │   │   │   │   ├── development.md
│   │   │   │   │   ├── external-module.md
│   │   │   │   │   ├── icons.md
│   │   │   │   │   ├── route.md
│   │   │   │   │   ├── server.md
│   │   │   │   │   ├── settings.md
│   │   │   │   │   └── styles.md
│   │   │   │   ├── in-depth/
│   │   │   │   │   ├── access.md
│   │   │   │   │   ├── check-updates.md
│   │   │   │   │   ├── features.md
│   │   │   │   │   ├── layout.md
│   │   │   │   │   ├── loading.md
│   │   │   │   │   ├── locale.md
│   │   │   │   │   ├── login.md
│   │   │   │   │   ├── theme.md
│   │   │   │   │   └── ui-framework.md
│   │   │   │   ├── introduction/
│   │   │   │   │   ├── changelog.md
│   │   │   │   │   ├── quick-start.md
│   │   │   │   │   ├── roadmap.md
│   │   │   │   │   ├── thin.md
│   │   │   │   │   ├── vben.md
│   │   │   │   │   └── why.md
│   │   │   │   ├── other/
│   │   │   │   │   ├── faq.md
│   │   │   │   │   ├── project-update.md
│   │   │   │   │   └── remove-code.md
│   │   │   │   └── project/
│   │   │   │       ├── changeset.md
│   │   │   │       ├── cli.md
│   │   │   │       ├── dir.md
│   │   │   │       ├── standard.md
│   │   │   │       ├── tailwindcss.md
│   │   │   │       ├── test.md
│   │   │   │       └── vite.md
│   │   │   ├── index.md
│   │   │   └── sponsor/
│   │   │       └── personal.md
│   │   ├── tailwind.config.mjs
│   │   └── tsconfig.json
│   ├── eslint.config.mjs
│   ├── internal/
│   │   ├── lint-configs/
│   │   │   ├── commitlint-config/
│   │   │   │   ├── index.mjs
│   │   │   │   └── package.json
│   │   │   ├── eslint-config/
│   │   │   │   ├── build.config.ts
│   │   │   │   ├── package.json
│   │   │   │   ├── src/
│   │   │   │   │   ├── configs/
│   │   │   │   │   │   ├── command.ts
│   │   │   │   │   │   ├── comments.ts
│   │   │   │   │   │   ├── disableds.ts
│   │   │   │   │   │   ├── ignores.ts
│   │   │   │   │   │   ├── import.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── javascript.ts
│   │   │   │   │   │   ├── jsdoc.ts
│   │   │   │   │   │   ├── jsonc.ts
│   │   │   │   │   │   ├── node.ts
│   │   │   │   │   │   ├── perfectionist.ts
│   │   │   │   │   │   ├── prettier.ts
│   │   │   │   │   │   ├── regexp.ts
│   │   │   │   │   │   ├── test.ts
│   │   │   │   │   │   ├── turbo.ts
│   │   │   │   │   │   ├── typescript.ts
│   │   │   │   │   │   ├── unicorn.ts
│   │   │   │   │   │   └── vue.ts
│   │   │   │   │   ├── custom-config.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── util.ts
│   │   │   │   └── tsconfig.json
│   │   │   ├── prettier-config/
│   │   │   │   ├── index.mjs
│   │   │   │   └── package.json
│   │   │   └── stylelint-config/
│   │   │       ├── index.mjs
│   │   │       └── package.json
│   │   ├── node-utils/
│   │   │   ├── build.config.ts
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── __tests__/
│   │   │   │   │   ├── hash.test.ts
│   │   │   │   │   └── path.test.ts
│   │   │   │   ├── constants.ts
│   │   │   │   ├── date.ts
│   │   │   │   ├── fs.ts
│   │   │   │   ├── git.ts
│   │   │   │   ├── hash.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── monorepo.ts
│   │   │   │   ├── path.ts
│   │   │   │   ├── prettier.ts
│   │   │   │   └── spinner.ts
│   │   │   └── tsconfig.json
│   │   ├── tailwind-config/
│   │   │   ├── build.config.ts
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── index.ts
│   │   │   │   ├── module.d.ts
│   │   │   │   ├── plugins/
│   │   │   │   │   └── entry.ts
│   │   │   │   └── postcss.config.ts
│   │   │   └── tsconfig.json
│   │   ├── tsconfig/
│   │   │   ├── base.json
│   │   │   ├── library.json
│   │   │   ├── node.json
│   │   │   ├── package.json
│   │   │   ├── web-app.json
│   │   │   └── web.json
│   │   └── vite-config/
│   │       ├── build.config.ts
│   │       ├── package.json
│   │       ├── src/
│   │       │   ├── config/
│   │       │   │   ├── application.ts
│   │       │   │   ├── common.ts
│   │       │   │   ├── index.ts
│   │       │   │   └── library.ts
│   │       │   ├── index.ts
│   │       │   ├── options.ts
│   │       │   ├── plugins/
│   │       │   │   ├── archiver.ts
│   │       │   │   ├── extra-app-config.ts
│   │       │   │   ├── importmap.ts
│   │       │   │   ├── index.ts
│   │       │   │   ├── inject-app-loading/
│   │       │   │   │   ├── README.md
│   │       │   │   │   ├── default-loading-antd.html
│   │       │   │   │   ├── default-loading.html
│   │       │   │   │   └── index.ts
│   │       │   │   ├── inject-metadata.ts
│   │       │   │   ├── license.ts
│   │       │   │   ├── nitro-mock.ts
│   │       │   │   ├── print.ts
│   │       │   │   └── vxe-table.ts
│   │       │   ├── typing.ts
│   │       │   └── utils/
│   │       │       └── env.ts
│   │       └── tsconfig.json
│   ├── package.json
│   ├── packages/
│   │   ├── @core/
│   │   │   ├── README.md
│   │   │   ├── base/
│   │   │   │   ├── README.md
│   │   │   │   ├── design/
│   │   │   │   │   ├── package.json
│   │   │   │   │   ├── src/
│   │   │   │   │   │   ├── css/
│   │   │   │   │   │   │   ├── global.css
│   │   │   │   │   │   │   ├── nprogress.css
│   │   │   │   │   │   │   ├── transition.css
│   │   │   │   │   │   │   └── ui.css
│   │   │   │   │   │   ├── design-tokens/
│   │   │   │   │   │   │   ├── dark.css
│   │   │   │   │   │   │   ├── default.css
│   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── scss-bem/
│   │   │   │   │   │       ├── bem.scss
│   │   │   │   │   │       └── constants.scss
│   │   │   │   │   ├── tsconfig.json
│   │   │   │   │   └── vite.config.mts
│   │   │   │   ├── icons/
│   │   │   │   │   ├── build.config.ts
│   │   │   │   │   ├── package.json
│   │   │   │   │   ├── src/
│   │   │   │   │   │   ├── create-icon.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── lucide.ts
│   │   │   │   │   └── tsconfig.json
│   │   │   │   ├── shared/
│   │   │   │   │   ├── build.config.ts
│   │   │   │   │   ├── package.json
│   │   │   │   │   ├── src/
│   │   │   │   │   │   ├── cache/
│   │   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   │   └── storage-manager.test.ts
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   ├── storage-manager.ts
│   │   │   │   │   │   │   └── types.ts
│   │   │   │   │   │   ├── color/
│   │   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   │   └── convert.test.ts
│   │   │   │   │   │   │   ├── color.ts
│   │   │   │   │   │   │   ├── convert.ts
│   │   │   │   │   │   │   ├── generator.ts
│   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   ├── constants/
│   │   │   │   │   │   │   ├── globals.ts
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   └── vben.ts
│   │   │   │   │   │   ├── global-state.ts
│   │   │   │   │   │   ├── store.ts
│   │   │   │   │   │   └── utils/
│   │   │   │   │   │       ├── __tests__/
│   │   │   │   │   │       │   ├── diff.test.ts
│   │   │   │   │   │       │   ├── dom.test.ts
│   │   │   │   │   │       │   ├── inference.test.ts
│   │   │   │   │   │       │   ├── letter.test.ts
│   │   │   │   │   │       │   ├── resources.test.ts
│   │   │   │   │   │       │   ├── state-handler.test.ts
│   │   │   │   │   │       │   ├── tree.test.ts
│   │   │   │   │   │       │   ├── unique.test.ts
│   │   │   │   │   │       │   ├── update-css-variables.test.ts
│   │   │   │   │   │       │   ├── util.test.ts
│   │   │   │   │   │       │   └── window.test.ts
│   │   │   │   │   │       ├── cn.ts
│   │   │   │   │   │       ├── date.ts
│   │   │   │   │   │       ├── diff.ts
│   │   │   │   │   │       ├── dom.ts
│   │   │   │   │   │       ├── download.ts
│   │   │   │   │   │       ├── index.ts
│   │   │   │   │   │       ├── inference.ts
│   │   │   │   │   │       ├── letter.ts
│   │   │   │   │   │       ├── merge.ts
│   │   │   │   │   │       ├── nprogress.ts
│   │   │   │   │   │       ├── resources.ts
│   │   │   │   │   │       ├── state-handler.ts
│   │   │   │   │   │       ├── to.ts
│   │   │   │   │   │       ├── tree.ts
│   │   │   │   │   │       ├── unique.ts
│   │   │   │   │   │       ├── update-css-variables.ts
│   │   │   │   │   │       ├── util.ts
│   │   │   │   │   │       └── window.ts
│   │   │   │   │   └── tsconfig.json
│   │   │   │   └── typings/
│   │   │   │       ├── build.config.ts
│   │   │   │       ├── package.json
│   │   │   │       ├── src/
│   │   │   │       │   ├── app.d.ts
│   │   │   │       │   ├── basic.d.ts
│   │   │   │       │   ├── helper.d.ts
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── menu-record.ts
│   │   │   │       │   ├── tabs.ts
│   │   │   │       │   └── vue-router.d.ts
│   │   │   │       ├── tsconfig.json
│   │   │   │       └── vue-router.d.ts
│   │   │   ├── composables/
│   │   │   │   ├── build.config.ts
│   │   │   │   ├── package.json
│   │   │   │   ├── src/
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   └── use-sortable.test.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── use-is-mobile.ts
│   │   │   │   │   ├── use-layout-style.ts
│   │   │   │   │   ├── use-namespace.ts
│   │   │   │   │   ├── use-priority-value.ts
│   │   │   │   │   ├── use-scroll-lock.ts
│   │   │   │   │   ├── use-simple-locale/
│   │   │   │   │   │   ├── README.md
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── messages.ts
│   │   │   │   │   └── use-sortable.ts
│   │   │   │   └── tsconfig.json
│   │   │   ├── preferences/
│   │   │   │   ├── __tests__/
│   │   │   │   │   ├── __snapshots__/
│   │   │   │   │   │   └── config.test.ts.snap
│   │   │   │   │   ├── config.test.ts
│   │   │   │   │   └── preferences.test.ts
│   │   │   │   ├── build.config.ts
│   │   │   │   ├── package.json
│   │   │   │   ├── src/
│   │   │   │   │   ├── config.ts
│   │   │   │   │   ├── constants.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── preferences.ts
│   │   │   │   │   ├── types.ts
│   │   │   │   │   ├── update-css-variables.ts
│   │   │   │   │   └── use-preferences.ts
│   │   │   │   └── tsconfig.json
│   │   │   └── ui-kit/
│   │   │       ├── README.md
│   │   │       ├── form-ui/
│   │   │       │   ├── __tests__/
│   │   │       │   │   └── form-api.test.ts
│   │   │       │   ├── build.config.ts
│   │   │       │   ├── package.json
│   │   │       │   ├── postcss.config.mjs
│   │   │       │   ├── src/
│   │   │       │   │   ├── components/
│   │   │       │   │   │   └── form-actions.vue
│   │   │       │   │   ├── config.ts
│   │   │       │   │   ├── form-api.ts
│   │   │       │   │   ├── form-render/
│   │   │       │   │   │   ├── context.ts
│   │   │       │   │   │   ├── dependencies.ts
│   │   │       │   │   │   ├── expandable.ts
│   │   │       │   │   │   ├── form-field.vue
│   │   │       │   │   │   ├── form-label.vue
│   │   │       │   │   │   ├── form.vue
│   │   │       │   │   │   ├── helper.ts
│   │   │       │   │   │   └── index.ts
│   │   │       │   │   ├── index.ts
│   │   │       │   │   ├── types.ts
│   │   │       │   │   ├── use-form-context.ts
│   │   │       │   │   ├── use-vben-form.ts
│   │   │       │   │   ├── vben-form.vue
│   │   │       │   │   └── vben-use-form.vue
│   │   │       │   ├── tailwind.config.mjs
│   │   │       │   └── tsconfig.json
│   │   │       ├── layout-ui/
│   │   │       │   ├── build.config.ts
│   │   │       │   ├── package.json
│   │   │       │   ├── postcss.config.mjs
│   │   │       │   ├── src/
│   │   │       │   │   ├── components/
│   │   │       │   │   │   ├── index.ts
│   │   │       │   │   │   ├── layout-content.vue
│   │   │       │   │   │   ├── layout-footer.vue
│   │   │       │   │   │   ├── layout-header.vue
│   │   │       │   │   │   ├── layout-sidebar.vue
│   │   │       │   │   │   ├── layout-tabbar.vue
│   │   │       │   │   │   └── widgets/
│   │   │       │   │   │       ├── index.ts
│   │   │       │   │   │       ├── sidebar-collapse-button.vue
│   │   │       │   │   │       └── sidebar-fixed-button.vue
│   │   │       │   │   ├── hooks/
│   │   │       │   │   │   └── use-layout.ts
│   │   │       │   │   ├── index.ts
│   │   │       │   │   ├── vben-layout.ts
│   │   │       │   │   └── vben-layout.vue
│   │   │       │   ├── tailwind.config.mjs
│   │   │       │   └── tsconfig.json
│   │   │       ├── menu-ui/
│   │   │       │   ├── README.md
│   │   │       │   ├── build.config.ts
│   │   │       │   ├── package.json
│   │   │       │   ├── postcss.config.mjs
│   │   │       │   ├── src/
│   │   │       │   │   ├── components/
│   │   │       │   │   │   ├── collapse-transition.vue
│   │   │       │   │   │   ├── index.ts
│   │   │       │   │   │   ├── menu-badge-dot.vue
│   │   │       │   │   │   ├── menu-badge.vue
│   │   │       │   │   │   ├── menu-item.vue
│   │   │       │   │   │   ├── menu.vue
│   │   │       │   │   │   ├── normal-menu/
│   │   │       │   │   │   │   ├── index.ts
│   │   │       │   │   │   │   ├── normal-menu.ts
│   │   │       │   │   │   │   └── normal-menu.vue
│   │   │       │   │   │   ├── sub-menu-content.vue
│   │   │       │   │   │   └── sub-menu.vue
│   │   │       │   │   ├── hooks/
│   │   │       │   │   │   ├── index.ts
│   │   │       │   │   │   ├── use-menu-context.ts
│   │   │       │   │   │   ├── use-menu-scroll.ts
│   │   │       │   │   │   └── use-menu.ts
│   │   │       │   │   ├── index.ts
│   │   │       │   │   ├── menu.vue
│   │   │       │   │   ├── sub-menu.vue
│   │   │       │   │   ├── types.ts
│   │   │       │   │   └── utils/
│   │   │       │   │       └── index.ts
│   │   │       │   ├── tailwind.config.mjs
│   │   │       │   └── tsconfig.json
│   │   │       ├── popup-ui/
│   │   │       │   ├── build.config.ts
│   │   │       │   ├── package.json
│   │   │       │   ├── postcss.config.mjs
│   │   │       │   ├── src/
│   │   │       │   │   ├── alert/
│   │   │       │   │   │   ├── AlertBuilder.ts
│   │   │       │   │   │   ├── alert.ts
│   │   │       │   │   │   ├── alert.vue
│   │   │       │   │   │   └── index.ts
│   │   │       │   │   ├── drawer/
│   │   │       │   │   │   ├── __tests__/
│   │   │       │   │   │   │   └── drawer-api.test.ts
│   │   │       │   │   │   ├── drawer-api.ts
│   │   │       │   │   │   ├── drawer.ts
│   │   │       │   │   │   ├── drawer.vue
│   │   │       │   │   │   ├── index.ts
│   │   │       │   │   │   └── use-drawer.ts
│   │   │       │   │   ├── index.ts
│   │   │       │   │   └── modal/
│   │   │       │   │       ├── __tests__/
│   │   │       │   │       │   └── modal-api.test.ts
│   │   │       │   │       ├── index.ts
│   │   │       │   │       ├── modal-api.ts
│   │   │       │   │       ├── modal.ts
│   │   │       │   │       ├── modal.vue
│   │   │       │   │       ├── use-modal-draggable.ts
│   │   │       │   │       └── use-modal.ts
│   │   │       │   ├── tailwind.config.mjs
│   │   │       │   └── tsconfig.json
│   │   │       ├── shadcn-ui/
│   │   │       │   ├── build.config.ts
│   │   │       │   ├── components.json
│   │   │       │   ├── package.json
│   │   │       │   ├── postcss.config.mjs
│   │   │       │   ├── src/
│   │   │       │   │   ├── components/
│   │   │       │   │   │   ├── avatar/
│   │   │       │   │   │   │   ├── avatar.vue
│   │   │       │   │   │   │   └── index.ts
│   │   │       │   │   │   ├── back-top/
│   │   │       │   │   │   │   ├── back-top.vue
│   │   │       │   │   │   │   ├── backtop.ts
│   │   │       │   │   │   │   ├── index.ts
│   │   │       │   │   │   │   └── use-backtop.ts
│   │   │       │   │   │   ├── breadcrumb/
│   │   │       │   │   │   │   ├── breadcrumb-background.vue
│   │   │       │   │   │   │   ├── breadcrumb-view.vue
│   │   │       │   │   │   │   ├── breadcrumb.vue
│   │   │       │   │   │   │   ├── index.ts
│   │   │       │   │   │   │   └── types.ts
│   │   │       │   │   │   ├── button/
│   │   │       │   │   │   │   ├── button-group.vue
│   │   │       │   │   │   │   ├── button.ts
│   │   │       │   │   │   │   ├── button.vue
│   │   │       │   │   │   │   ├── check-button-group.vue
│   │   │       │   │   │   │   ├── icon-button.vue
│   │   │       │   │   │   │   └── index.ts
│   │   │       │   │   │   ├── checkbox/
│   │   │       │   │   │   │   ├── checkbox.vue
│   │   │       │   │   │   │   └── index.ts
│   │   │       │   │   │   ├── context-menu/
│   │   │       │   │   │   │   ├── context-menu.vue
│   │   │       │   │   │   │   ├── index.ts
│   │   │       │   │   │   │   └── interface.ts
│   │   │       │   │   │   ├── count-to-animator/
│   │   │       │   │   │   │   ├── count-to-animator.vue
│   │   │       │   │   │   │   └── index.ts
│   │   │       │   │   │   ├── dropdown-menu/
│   │   │       │   │   │   │   ├── dropdown-menu.vue
│   │   │       │   │   │   │   ├── dropdown-radio-menu.vue
│   │   │       │   │   │   │   ├── index.ts
│   │   │       │   │   │   │   └── interface.ts
│   │   │       │   │   │   ├── expandable-arrow/
│   │   │       │   │   │   │   ├── expandable-arrow.vue
│   │   │       │   │   │   │   └── index.ts
│   │   │       │   │   │   ├── full-screen/
│   │   │       │   │   │   │   ├── full-screen.vue
│   │   │       │   │   │   │   └── index.ts
│   │   │       │   │   │   ├── hover-card/
│   │   │       │   │   │   │   ├── hover-card.vue
│   │   │       │   │   │   │   └── index.ts
│   │   │       │   │   │   ├── icon/
│   │   │       │   │   │   │   ├── icon.vue
│   │   │       │   │   │   │   └── index.ts
│   │   │       │   │   │   ├── index.ts
│   │   │       │   │   │   ├── input-password/
│   │   │       │   │   │   │   ├── index.ts
│   │   │       │   │   │   │   ├── input-password.vue
│   │   │       │   │   │   │   └── password-strength.vue
│   │   │       │   │   │   ├── logo/
│   │   │       │   │   │   │   ├── index.ts
│   │   │       │   │   │   │   └── logo.vue
│   │   │       │   │   │   ├── pin-input/
│   │   │       │   │   │   │   ├── index.ts
│   │   │       │   │   │   │   ├── input.vue
│   │   │       │   │   │   │   └── types.ts
│   │   │       │   │   │   ├── popover/
│   │   │       │   │   │   │   ├── index.ts
│   │   │       │   │   │   │   └── popover.vue
│   │   │       │   │   │   ├── render-content/
│   │   │       │   │   │   │   ├── index.ts
│   │   │       │   │   │   │   └── render-content.vue
│   │   │       │   │   │   ├── scrollbar/
│   │   │       │   │   │   │   ├── index.ts
│   │   │       │   │   │   │   └── scrollbar.vue
│   │   │       │   │   │   ├── segmented/
│   │   │       │   │   │   │   ├── index.ts
│   │   │       │   │   │   │   ├── segmented.vue
│   │   │       │   │   │   │   ├── tabs-indicator.vue
│   │   │       │   │   │   │   └── types.ts
│   │   │       │   │   │   ├── select/
│   │   │       │   │   │   │   ├── index.ts
│   │   │       │   │   │   │   └── select.vue
│   │   │       │   │   │   ├── spine-text/
│   │   │       │   │   │   │   ├── index.ts
│   │   │       │   │   │   │   └── spine-text.vue
│   │   │       │   │   │   ├── spinner/
│   │   │       │   │   │   │   ├── index.ts
│   │   │       │   │   │   │   ├── loading.vue
│   │   │       │   │   │   │   └── spinner.vue
│   │   │       │   │   │   └── tooltip/
│   │   │       │   │   │       ├── help-tooltip.vue
│   │   │       │   │   │       ├── index.ts
│   │   │       │   │   │       └── tooltip.vue
│   │   │       │   │   ├── index.ts
│   │   │       │   │   └── ui/
│   │   │       │   │       ├── accordion/
│   │   │       │   │       │   ├── Accordion.vue
│   │   │       │   │       │   ├── AccordionContent.vue
│   │   │       │   │       │   ├── AccordionItem.vue
│   │   │       │   │       │   ├── AccordionTrigger.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── alert-dialog/
│   │   │       │   │       │   ├── AlertDialog.vue
│   │   │       │   │       │   ├── AlertDialogAction.vue
│   │   │       │   │       │   ├── AlertDialogCancel.vue
│   │   │       │   │       │   ├── AlertDialogContent.vue
│   │   │       │   │       │   ├── AlertDialogDescription.vue
│   │   │       │   │       │   ├── AlertDialogOverlay.vue
│   │   │       │   │       │   ├── AlertDialogTitle.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── avatar/
│   │   │       │   │       │   ├── Avatar.vue
│   │   │       │   │       │   ├── AvatarFallback.vue
│   │   │       │   │       │   ├── AvatarImage.vue
│   │   │       │   │       │   ├── avatar.ts
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── badge/
│   │   │       │   │       │   ├── Badge.vue
│   │   │       │   │       │   ├── badge.ts
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── breadcrumb/
│   │   │       │   │       │   ├── Breadcrumb.vue
│   │   │       │   │       │   ├── BreadcrumbEllipsis.vue
│   │   │       │   │       │   ├── BreadcrumbItem.vue
│   │   │       │   │       │   ├── BreadcrumbLink.vue
│   │   │       │   │       │   ├── BreadcrumbList.vue
│   │   │       │   │       │   ├── BreadcrumbPage.vue
│   │   │       │   │       │   ├── BreadcrumbSeparator.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── button/
│   │   │       │   │       │   ├── Button.vue
│   │   │       │   │       │   ├── button.ts
│   │   │       │   │       │   ├── index.ts
│   │   │       │   │       │   └── types.ts
│   │   │       │   │       ├── card/
│   │   │       │   │       │   ├── Card.vue
│   │   │       │   │       │   ├── CardContent.vue
│   │   │       │   │       │   ├── CardDescription.vue
│   │   │       │   │       │   ├── CardFooter.vue
│   │   │       │   │       │   ├── CardHeader.vue
│   │   │       │   │       │   ├── CardTitle.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── checkbox/
│   │   │       │   │       │   ├── Checkbox.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── context-menu/
│   │   │       │   │       │   ├── ContextMenu.vue
│   │   │       │   │       │   ├── ContextMenuCheckboxItem.vue
│   │   │       │   │       │   ├── ContextMenuContent.vue
│   │   │       │   │       │   ├── ContextMenuGroup.vue
│   │   │       │   │       │   ├── ContextMenuItem.vue
│   │   │       │   │       │   ├── ContextMenuLabel.vue
│   │   │       │   │       │   ├── ContextMenuPortal.vue
│   │   │       │   │       │   ├── ContextMenuRadioGroup.vue
│   │   │       │   │       │   ├── ContextMenuRadioItem.vue
│   │   │       │   │       │   ├── ContextMenuSeparator.vue
│   │   │       │   │       │   ├── ContextMenuShortcut.vue
│   │   │       │   │       │   ├── ContextMenuSub.vue
│   │   │       │   │       │   ├── ContextMenuSubContent.vue
│   │   │       │   │       │   ├── ContextMenuSubTrigger.vue
│   │   │       │   │       │   ├── ContextMenuTrigger.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── dialog/
│   │   │       │   │       │   ├── Dialog.vue
│   │   │       │   │       │   ├── DialogClose.vue
│   │   │       │   │       │   ├── DialogContent.vue
│   │   │       │   │       │   ├── DialogDescription.vue
│   │   │       │   │       │   ├── DialogFooter.vue
│   │   │       │   │       │   ├── DialogHeader.vue
│   │   │       │   │       │   ├── DialogOverlay.vue
│   │   │       │   │       │   ├── DialogScrollContent.vue
│   │   │       │   │       │   ├── DialogTitle.vue
│   │   │       │   │       │   ├── DialogTrigger.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── dropdown-menu/
│   │   │       │   │       │   ├── DropdownMenu.vue
│   │   │       │   │       │   ├── DropdownMenuCheckboxItem.vue
│   │   │       │   │       │   ├── DropdownMenuContent.vue
│   │   │       │   │       │   ├── DropdownMenuGroup.vue
│   │   │       │   │       │   ├── DropdownMenuItem.vue
│   │   │       │   │       │   ├── DropdownMenuLabel.vue
│   │   │       │   │       │   ├── DropdownMenuRadioGroup.vue
│   │   │       │   │       │   ├── DropdownMenuRadioItem.vue
│   │   │       │   │       │   ├── DropdownMenuSeparator.vue
│   │   │       │   │       │   ├── DropdownMenuShortcut.vue
│   │   │       │   │       │   ├── DropdownMenuSub.vue
│   │   │       │   │       │   ├── DropdownMenuSubContent.vue
│   │   │       │   │       │   ├── DropdownMenuSubTrigger.vue
│   │   │       │   │       │   ├── DropdownMenuTrigger.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── form/
│   │   │       │   │       │   ├── FormControl.vue
│   │   │       │   │       │   ├── FormDescription.vue
│   │   │       │   │       │   ├── FormItem.vue
│   │   │       │   │       │   ├── FormLabel.vue
│   │   │       │   │       │   ├── FormMessage.vue
│   │   │       │   │       │   ├── index.ts
│   │   │       │   │       │   ├── injectionKeys.ts
│   │   │       │   │       │   └── useFormField.ts
│   │   │       │   │       ├── hover-card/
│   │   │       │   │       │   ├── HoverCard.vue
│   │   │       │   │       │   ├── HoverCardContent.vue
│   │   │       │   │       │   ├── HoverCardTrigger.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── index.ts
│   │   │       │   │       ├── input/
│   │   │       │   │       │   ├── Input.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── label/
│   │   │       │   │       │   ├── Label.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── number-field/
│   │   │       │   │       │   ├── NumberField.vue
│   │   │       │   │       │   ├── NumberFieldContent.vue
│   │   │       │   │       │   ├── NumberFieldDecrement.vue
│   │   │       │   │       │   ├── NumberFieldIncrement.vue
│   │   │       │   │       │   ├── NumberFieldInput.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── pagination/
│   │   │       │   │       │   ├── PaginationEllipsis.vue
│   │   │       │   │       │   ├── PaginationFirst.vue
│   │   │       │   │       │   ├── PaginationLast.vue
│   │   │       │   │       │   ├── PaginationNext.vue
│   │   │       │   │       │   ├── PaginationPrev.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── pin-input/
│   │   │       │   │       │   ├── PinInput.vue
│   │   │       │   │       │   ├── PinInputGroup.vue
│   │   │       │   │       │   ├── PinInputInput.vue
│   │   │       │   │       │   ├── PinInputSeparator.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── popover/
│   │   │       │   │       │   ├── Popover.vue
│   │   │       │   │       │   ├── PopoverContent.vue
│   │   │       │   │       │   ├── PopoverTrigger.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── radio-group/
│   │   │       │   │       │   ├── RadioGroup.vue
│   │   │       │   │       │   ├── RadioGroupItem.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── resizable/
│   │   │       │   │       │   ├── ResizableHandle.vue
│   │   │       │   │       │   ├── ResizablePanelGroup.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── scroll-area/
│   │   │       │   │       │   ├── ScrollArea.vue
│   │   │       │   │       │   ├── ScrollBar.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── select/
│   │   │       │   │       │   ├── Select.vue
│   │   │       │   │       │   ├── SelectContent.vue
│   │   │       │   │       │   ├── SelectGroup.vue
│   │   │       │   │       │   ├── SelectItem.vue
│   │   │       │   │       │   ├── SelectItemText.vue
│   │   │       │   │       │   ├── SelectLabel.vue
│   │   │       │   │       │   ├── SelectScrollDownButton.vue
│   │   │       │   │       │   ├── SelectScrollUpButton.vue
│   │   │       │   │       │   ├── SelectSeparator.vue
│   │   │       │   │       │   ├── SelectTrigger.vue
│   │   │       │   │       │   ├── SelectValue.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── separator/
│   │   │       │   │       │   ├── Separator.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── sheet/
│   │   │       │   │       │   ├── Sheet.vue
│   │   │       │   │       │   ├── SheetClose.vue
│   │   │       │   │       │   ├── SheetContent.vue
│   │   │       │   │       │   ├── SheetDescription.vue
│   │   │       │   │       │   ├── SheetFooter.vue
│   │   │       │   │       │   ├── SheetHeader.vue
│   │   │       │   │       │   ├── SheetOverlay.vue
│   │   │       │   │       │   ├── SheetTitle.vue
│   │   │       │   │       │   ├── SheetTrigger.vue
│   │   │       │   │       │   ├── index.ts
│   │   │       │   │       │   └── sheet.ts
│   │   │       │   │       ├── switch/
│   │   │       │   │       │   ├── Switch.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── tabs/
│   │   │       │   │       │   ├── Tabs.vue
│   │   │       │   │       │   ├── TabsContent.vue
│   │   │       │   │       │   ├── TabsList.vue
│   │   │       │   │       │   ├── TabsTrigger.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── textarea/
│   │   │       │   │       │   ├── Textarea.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── toggle/
│   │   │       │   │       │   ├── Toggle.vue
│   │   │       │   │       │   ├── index.ts
│   │   │       │   │       │   └── toggle.ts
│   │   │       │   │       ├── toggle-group/
│   │   │       │   │       │   ├── ToggleGroup.vue
│   │   │       │   │       │   ├── ToggleGroupItem.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── tooltip/
│   │   │       │   │       │   ├── Tooltip.vue
│   │   │       │   │       │   ├── TooltipContent.vue
│   │   │       │   │       │   ├── TooltipProvider.vue
│   │   │       │   │       │   ├── TooltipTrigger.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       └── tree/
│   │   │       │   │           ├── index.ts
│   │   │       │   │           ├── tree.vue
│   │   │       │   │           └── types.ts
│   │   │       │   ├── tailwind.config.mjs
│   │   │       │   └── tsconfig.json
│   │   │       └── tabs-ui/
│   │   │           ├── build.config.ts
│   │   │           ├── package.json
│   │   │           ├── postcss.config.mjs
│   │   │           ├── src/
│   │   │           │   ├── components/
│   │   │           │   │   ├── index.ts
│   │   │           │   │   ├── tabs/
│   │   │           │   │   │   └── tabs.vue
│   │   │           │   │   ├── tabs-chrome/
│   │   │           │   │   │   └── tabs.vue
│   │   │           │   │   └── widgets/
│   │   │           │   │       ├── index.ts
│   │   │           │   │       ├── tool-more.vue
│   │   │           │   │       └── tool-screen.vue
│   │   │           │   ├── index.ts
│   │   │           │   ├── tabs-view.vue
│   │   │           │   ├── types.ts
│   │   │           │   ├── use-tabs-drag.ts
│   │   │           │   └── use-tabs-view-scroll.ts
│   │   │           ├── tailwind.config.mjs
│   │   │           └── tsconfig.json
│   │   ├── constants/
│   │   │   ├── README.md
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── core.ts
│   │   │   │   └── index.ts
│   │   │   └── tsconfig.json
│   │   ├── effects/
│   │   │   ├── README.md
│   │   │   ├── access/
│   │   │   │   ├── package.json
│   │   │   │   ├── src/
│   │   │   │   │   ├── access-control.vue
│   │   │   │   │   ├── accessible.ts
│   │   │   │   │   ├── directive.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── use-access.ts
│   │   │   │   └── tsconfig.json
│   │   │   ├── common-ui/
│   │   │   │   ├── package.json
│   │   │   │   ├── src/
│   │   │   │   │   ├── components/
│   │   │   │   │   │   ├── api-component/
│   │   │   │   │   │   │   ├── api-component.vue
│   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   ├── captcha/
│   │   │   │   │   │   │   ├── hooks/
│   │   │   │   │   │   │   │   └── useCaptchaPoints.ts
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   ├── point-selection-captcha/
│   │   │   │   │   │   │   │   ├── index.vue
│   │   │   │   │   │   │   │   └── point-selection-captcha-card.vue
│   │   │   │   │   │   │   ├── slider-captcha/
│   │   │   │   │   │   │   │   ├── index.vue
│   │   │   │   │   │   │   │   ├── slider-captcha-action.vue
│   │   │   │   │   │   │   │   ├── slider-captcha-bar.vue
│   │   │   │   │   │   │   │   └── slider-captcha-content.vue
│   │   │   │   │   │   │   ├── slider-rotate-captcha/
│   │   │   │   │   │   │   │   └── index.vue
│   │   │   │   │   │   │   ├── slider-translate-captcha/
│   │   │   │   │   │   │   │   └── index.vue
│   │   │   │   │   │   │   └── types.ts
│   │   │   │   │   │   ├── col-page/
│   │   │   │   │   │   │   ├── col-page.vue
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   └── types.ts
│   │   │   │   │   │   ├── count-to/
│   │   │   │   │   │   │   ├── count-to.vue
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   └── types.ts
│   │   │   │   │   │   ├── ellipsis-text/
│   │   │   │   │   │   │   ├── ellipsis-text.vue
│   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   ├── icon-picker/
│   │   │   │   │   │   │   ├── icon-picker.vue
│   │   │   │   │   │   │   ├── icons.ts
│   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── json-viewer/
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   ├── index.vue
│   │   │   │   │   │   │   ├── style.scss
│   │   │   │   │   │   │   └── types.ts
│   │   │   │   │   │   ├── loading/
│   │   │   │   │   │   │   ├── directive.ts
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   ├── loading.vue
│   │   │   │   │   │   │   └── spinner.vue
│   │   │   │   │   │   ├── page/
│   │   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   │   └── page.test.ts
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   ├── page.vue
│   │   │   │   │   │   │   └── types.ts
│   │   │   │   │   │   ├── resize/
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   └── resize.vue
│   │   │   │   │   │   ├── tippy/
│   │   │   │   │   │   │   ├── directive.ts
│   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   └── tree/
│   │   │   │   │   │       ├── index.ts
│   │   │   │   │   │       └── tree.vue
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── ui/
│   │   │   │   │       ├── about/
│   │   │   │   │       │   ├── about.ts
│   │   │   │   │       │   ├── about.vue
│   │   │   │   │       │   └── index.ts
│   │   │   │   │       ├── authentication/
│   │   │   │   │       │   ├── auth-title.vue
│   │   │   │   │       │   ├── code-login.vue
│   │   │   │   │       │   ├── dingding-login.vue
│   │   │   │   │       │   ├── forget-password.vue
│   │   │   │   │       │   ├── index.ts
│   │   │   │   │       │   ├── login-expired-modal.vue
│   │   │   │   │       │   ├── login.vue
│   │   │   │   │       │   ├── qrcode-login.vue
│   │   │   │   │       │   ├── register.vue
│   │   │   │   │       │   ├── third-party-login.vue
│   │   │   │   │       │   └── types.ts
│   │   │   │   │       ├── dashboard/
│   │   │   │   │       │   ├── analysis/
│   │   │   │   │       │   │   ├── analysis-chart-card.vue
│   │   │   │   │       │   │   ├── analysis-charts-tabs.vue
│   │   │   │   │       │   │   ├── analysis-overview.vue
│   │   │   │   │       │   │   └── index.ts
│   │   │   │   │       │   ├── index.ts
│   │   │   │   │       │   ├── typing.ts
│   │   │   │   │       │   └── workbench/
│   │   │   │   │       │       ├── index.ts
│   │   │   │   │       │       ├── workbench-header.vue
│   │   │   │   │       │       ├── workbench-project.vue
│   │   │   │   │       │       ├── workbench-quick-nav.vue
│   │   │   │   │       │       ├── workbench-todo.vue
│   │   │   │   │       │       └── workbench-trends.vue
│   │   │   │   │       ├── fallback/
│   │   │   │   │       │   ├── fallback.ts
│   │   │   │   │       │   ├── fallback.vue
│   │   │   │   │       │   ├── icons/
│   │   │   │   │       │   │   ├── icon-403.vue
│   │   │   │   │       │   │   ├── icon-404.vue
│   │   │   │   │       │   │   ├── icon-500.vue
│   │   │   │   │       │   │   ├── icon-coming-soon.vue
│   │   │   │   │       │   │   └── icon-offline.vue
│   │   │   │   │       │   └── index.ts
│   │   │   │   │       └── index.ts
│   │   │   │   └── tsconfig.json
│   │   │   ├── hooks/
│   │   │   │   ├── README.md
│   │   │   │   ├── package.json
│   │   │   │   ├── src/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── use-app-config.ts
│   │   │   │   │   ├── use-content-maximize.ts
│   │   │   │   │   ├── use-design-tokens.ts
│   │   │   │   │   ├── use-hover-toggle.ts
│   │   │   │   │   ├── use-pagination.ts
│   │   │   │   │   ├── use-refresh.ts
│   │   │   │   │   ├── use-tabs.ts
│   │   │   │   │   └── use-watermark.ts
│   │   │   │   └── tsconfig.json
│   │   │   ├── layouts/
│   │   │   │   ├── package.json
│   │   │   │   ├── src/
│   │   │   │   │   ├── authentication/
│   │   │   │   │   │   ├── authentication.vue
│   │   │   │   │   │   ├── form.vue
│   │   │   │   │   │   ├── icons/
│   │   │   │   │   │   │   └── slogan.vue
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── toolbar.vue
│   │   │   │   │   │   └── types.ts
│   │   │   │   │   ├── basic/
│   │   │   │   │   │   ├── README.md
│   │   │   │   │   │   ├── content/
│   │   │   │   │   │   │   ├── content-spinner.vue
│   │   │   │   │   │   │   ├── content.vue
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   └── use-content-spinner.ts
│   │   │   │   │   │   ├── copyright/
│   │   │   │   │   │   │   ├── copyright.vue
│   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   ├── footer/
│   │   │   │   │   │   │   ├── footer.vue
│   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   ├── header/
│   │   │   │   │   │   │   ├── header.vue
│   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── layout.vue
│   │   │   │   │   │   ├── menu/
│   │   │   │   │   │   │   ├── extra-menu.vue
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   ├── menu.vue
│   │   │   │   │   │   │   ├── mixed-menu.vue
│   │   │   │   │   │   │   ├── use-extra-menu.ts
│   │   │   │   │   │   │   ├── use-mixed-menu.ts
│   │   │   │   │   │   │   └── use-navigation.ts
│   │   │   │   │   │   └── tabbar/
│   │   │   │   │   │       ├── index.ts
│   │   │   │   │   │       ├── tabbar.vue
│   │   │   │   │   │       └── use-tabbar.ts
│   │   │   │   │   ├── iframe/
│   │   │   │   │   │   ├── iframe-router-view.vue
│   │   │   │   │   │   ├── iframe-view.vue
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── widgets/
│   │   │   │   │       ├── breadcrumb.vue
│   │   │   │   │       ├── check-updates/
│   │   │   │   │       │   ├── check-updates.vue
│   │   │   │   │       │   └── index.ts
│   │   │   │   │       ├── color-toggle.vue
│   │   │   │   │       ├── global-search/
│   │   │   │   │       │   ├── global-search.vue
│   │   │   │   │       │   ├── index.ts
│   │   │   │   │       │   └── search-panel.vue
│   │   │   │   │       ├── index.ts
│   │   │   │   │       ├── language-toggle.vue
│   │   │   │   │       ├── layout-toggle.vue
│   │   │   │   │       ├── lock-screen/
│   │   │   │   │       │   ├── index.ts
│   │   │   │   │       │   ├── lock-screen-modal.vue
│   │   │   │   │       │   └── lock-screen.vue
│   │   │   │   │       ├── notification/
│   │   │   │   │       │   ├── index.ts
│   │   │   │   │       │   ├── notification.vue
│   │   │   │   │       │   └── types.ts
│   │   │   │   │       ├── preferences/
│   │   │   │   │       │   ├── blocks/
│   │   │   │   │       │   │   ├── block.vue
│   │   │   │   │       │   │   ├── checkbox-item.vue
│   │   │   │   │       │   │   ├── general/
│   │   │   │   │       │   │   │   ├── animation.vue
│   │   │   │   │       │   │   │   └── general.vue
│   │   │   │   │       │   │   ├── index.ts
│   │   │   │   │       │   │   ├── input-item.vue
│   │   │   │   │       │   │   ├── layout/
│   │   │   │   │       │   │   │   ├── breadcrumb.vue
│   │   │   │   │       │   │   │   ├── content.vue
│   │   │   │   │       │   │   │   ├── copyright.vue
│   │   │   │   │       │   │   │   ├── footer.vue
│   │   │   │   │       │   │   │   ├── header.vue
│   │   │   │   │       │   │   │   ├── layout.vue
│   │   │   │   │       │   │   │   ├── navigation.vue
│   │   │   │   │       │   │   │   ├── sidebar.vue
│   │   │   │   │       │   │   │   ├── tabbar.vue
│   │   │   │   │       │   │   │   └── widget.vue
│   │   │   │   │       │   │   ├── number-field-item.vue
│   │   │   │   │       │   │   ├── select-item.vue
│   │   │   │   │       │   │   ├── shortcut-keys/
│   │   │   │   │       │   │   │   └── global.vue
│   │   │   │   │       │   │   ├── switch-item.vue
│   │   │   │   │       │   │   ├── theme/
│   │   │   │   │       │   │   │   ├── builtin.vue
│   │   │   │   │       │   │   │   ├── color-mode.vue
│   │   │   │   │       │   │   │   ├── radius.vue
│   │   │   │   │       │   │   │   └── theme.vue
│   │   │   │   │       │   │   └── toggle-item.vue
│   │   │   │   │       │   ├── icons/
│   │   │   │   │       │   │   ├── content-compact.vue
│   │   │   │   │       │   │   ├── full-content.vue
│   │   │   │   │       │   │   ├── header-mixed-nav.vue
│   │   │   │   │       │   │   ├── header-nav.vue
│   │   │   │   │       │   │   ├── header-sidebar-nav.vue
│   │   │   │   │       │   │   ├── index.ts
│   │   │   │   │       │   │   ├── mixed-nav.vue
│   │   │   │   │       │   │   ├── setting.vue
│   │   │   │   │       │   │   ├── sidebar-mixed-nav.vue
│   │   │   │   │       │   │   └── sidebar-nav.vue
│   │   │   │   │       │   ├── index.ts
│   │   │   │   │       │   ├── preferences-button.vue
│   │   │   │   │       │   ├── preferences-drawer.vue
│   │   │   │   │       │   ├── preferences.vue
│   │   │   │   │       │   └── use-open-preferences.ts
│   │   │   │   │       ├── theme-toggle/
│   │   │   │   │       │   ├── index.ts
│   │   │   │   │       │   ├── theme-button.vue
│   │   │   │   │       │   └── theme-toggle.vue
│   │   │   │   │       └── user-dropdown/
│   │   │   │   │           ├── index.ts
│   │   │   │   │           └── user-dropdown.vue
│   │   │   │   └── tsconfig.json
│   │   │   ├── plugins/
│   │   │   │   ├── README.md
│   │   │   │   ├── package.json
│   │   │   │   ├── src/
│   │   │   │   │   ├── echarts/
│   │   │   │   │   │   ├── echarts-ui.vue
│   │   │   │   │   │   ├── echarts.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── use-echarts.ts
│   │   │   │   │   ├── motion/
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── types.ts
│   │   │   │   │   └── vxe-table/
│   │   │   │   │       ├── api.ts
│   │   │   │   │       ├── extends.ts
│   │   │   │   │       ├── index.ts
│   │   │   │   │       ├── init.ts
│   │   │   │   │       ├── style.css
│   │   │   │   │       ├── types.ts
│   │   │   │   │       ├── use-vxe-grid.ts
│   │   │   │   │       └── use-vxe-grid.vue
│   │   │   │   └── tsconfig.json
│   │   │   └── request/
│   │   │       ├── package.json
│   │   │       ├── src/
│   │   │       │   ├── index.ts
│   │   │       │   └── request-client/
│   │   │       │       ├── index.ts
│   │   │       │       ├── modules/
│   │   │       │       │   ├── downloader.test.ts
│   │   │       │       │   ├── downloader.ts
│   │   │       │       │   ├── interceptor.ts
│   │   │       │       │   ├── sse.test.ts
│   │   │       │       │   ├── sse.ts
│   │   │       │       │   ├── uploader.test.ts
│   │   │       │       │   └── uploader.ts
│   │   │       │       ├── preset-interceptors.ts
│   │   │       │       ├── request-client.test.ts
│   │   │       │       ├── request-client.ts
│   │   │       │       └── types.ts
│   │   │       └── tsconfig.json
│   │   ├── icons/
│   │   │   ├── README.md
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── iconify/
│   │   │   │   │   └── index.ts
│   │   │   │   ├── icons/
│   │   │   │   │   └── empty-icon.vue
│   │   │   │   ├── index.ts
│   │   │   │   └── svg/
│   │   │   │       ├── index.ts
│   │   │   │       └── load.ts
│   │   │   └── tsconfig.json
│   │   ├── locales/
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── i18n.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── langs/
│   │   │   │   │   ├── en-US/
│   │   │   │   │   │   ├── authentication.json
│   │   │   │   │   │   ├── common.json
│   │   │   │   │   │   ├── preferences.json
│   │   │   │   │   │   └── ui.json
│   │   │   │   │   └── zh-CN/
│   │   │   │   │       ├── authentication.json
│   │   │   │   │       ├── common.json
│   │   │   │   │       ├── preferences.json
│   │   │   │   │       └── ui.json
│   │   │   │   └── typing.ts
│   │   │   └── tsconfig.json
│   │   ├── preferences/
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   └── index.ts
│   │   │   └── tsconfig.json
│   │   ├── stores/
│   │   │   ├── package.json
│   │   │   ├── shim-pinia.d.ts
│   │   │   ├── src/
│   │   │   │   ├── index.ts
│   │   │   │   ├── modules/
│   │   │   │   │   ├── access.test.ts
│   │   │   │   │   ├── access.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── tabbar.test.ts
│   │   │   │   │   ├── tabbar.ts
│   │   │   │   │   ├── user.test.ts
│   │   │   │   │   └── user.ts
│   │   │   │   └── setup.ts
│   │   │   └── tsconfig.json
│   │   ├── styles/
│   │   │   ├── README.md
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── antd/
│   │   │   │   │   └── index.css
│   │   │   │   ├── ele/
│   │   │   │   │   └── index.css
│   │   │   │   ├── global/
│   │   │   │   │   └── index.scss
│   │   │   │   ├── index.ts
│   │   │   │   └── naive/
│   │   │   │       └── index.css
│   │   │   └── tsconfig.json
│   │   ├── types/
│   │   │   ├── README.md
│   │   │   ├── global.d.ts
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── index.ts
│   │   │   │   └── user.ts
│   │   │   └── tsconfig.json
│   │   └── utils/
│   │       ├── README.md
│   │       ├── package.json
│   │       ├── src/
│   │       │   ├── helpers/
│   │       │   │   ├── __tests__/
│   │       │   │   │   ├── find-menu-by-path.test.ts
│   │       │   │   │   ├── generate-menus.test.ts
│   │       │   │   │   ├── generate-routes-frontend.test.ts
│   │       │   │   │   └── merge-route-modules.test.ts
│   │       │   │   ├── find-menu-by-path.ts
│   │       │   │   ├── generate-menus.ts
│   │       │   │   ├── generate-routes-backend.ts
│   │       │   │   ├── generate-routes-frontend.ts
│   │       │   │   ├── get-popup-container.ts
│   │       │   │   ├── index.ts
│   │       │   │   ├── merge-route-modules.ts
│   │       │   │   ├── reset-routes.ts
│   │       │   │   └── unmount-global-loading.ts
│   │       │   └── index.ts
│   │       └── tsconfig.json
│   ├── playground/
│   │   ├── __tests__/
│   │   │   └── e2e/
│   │   │       ├── auth-login.spec.ts
│   │   │       └── common/
│   │   │           └── auth.ts
│   │   ├── index.html
│   │   ├── package.json
│   │   ├── playwright.config.ts
│   │   ├── postcss.config.mjs
│   │   ├── src/
│   │   │   ├── adapter/
│   │   │   │   ├── component/
│   │   │   │   │   └── index.ts
│   │   │   │   ├── form.ts
│   │   │   │   └── vxe-table.ts
│   │   │   ├── api/
│   │   │   │   ├── core/
│   │   │   │   │   ├── auth.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── menu.ts
│   │   │   │   │   └── user.ts
│   │   │   │   ├── examples/
│   │   │   │   │   ├── download.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── json-bigint.ts
│   │   │   │   │   ├── params.ts
│   │   │   │   │   ├── status.ts
│   │   │   │   │   ├── table.ts
│   │   │   │   │   └── upload.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── request.ts
│   │   │   │   └── system/
│   │   │   │       ├── dept.ts
│   │   │   │       ├── index.ts
│   │   │   │       ├── menu.ts
│   │   │   │       └── role.ts
│   │   │   ├── app.vue
│   │   │   ├── bootstrap.ts
│   │   │   ├── layouts/
│   │   │   │   ├── auth.vue
│   │   │   │   ├── basic.vue
│   │   │   │   └── index.ts
│   │   │   ├── locales/
│   │   │   │   ├── README.md
│   │   │   │   ├── index.ts
│   │   │   │   └── langs/
│   │   │   │       ├── en-US/
│   │   │   │       │   ├── demos.json
│   │   │   │       │   ├── examples.json
│   │   │   │       │   ├── page.json
│   │   │   │       │   └── system.json
│   │   │   │       └── zh-CN/
│   │   │   │           ├── demos.json
│   │   │   │           ├── examples.json
│   │   │   │           ├── page.json
│   │   │   │           └── system.json
│   │   │   ├── main.ts
│   │   │   ├── preferences.ts
│   │   │   ├── router/
│   │   │   │   ├── access.ts
│   │   │   │   ├── guard.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── routes/
│   │   │   │       ├── core.ts
│   │   │   │       ├── index.ts
│   │   │   │       └── modules/
│   │   │   │           ├── dashboard.ts
│   │   │   │           ├── demos.ts
│   │   │   │           ├── examples.ts
│   │   │   │           ├── system.ts
│   │   │   │           └── vben.ts
│   │   │   ├── store/
│   │   │   │   ├── auth.ts
│   │   │   │   └── index.ts
│   │   │   └── views/
│   │   │       ├── _core/
│   │   │       │   ├── README.md
│   │   │       │   ├── about/
│   │   │       │   │   └── index.vue
│   │   │       │   ├── authentication/
│   │   │       │   │   ├── code-login.vue
│   │   │       │   │   ├── forget-password.vue
│   │   │       │   │   ├── login.vue
│   │   │       │   │   ├── qrcode-login.vue
│   │   │       │   │   └── register.vue
│   │   │       │   └── fallback/
│   │   │       │       ├── coming-soon.vue
│   │   │       │       ├── forbidden.vue
│   │   │       │       ├── internal-error.vue
│   │   │       │       ├── not-found.vue
│   │   │       │       └── offline.vue
│   │   │       ├── dashboard/
│   │   │       │   ├── analytics/
│   │   │       │   │   ├── analytics-trends.vue
│   │   │       │   │   ├── analytics-visits-data.vue
│   │   │       │   │   ├── analytics-visits-sales.vue
│   │   │       │   │   ├── analytics-visits-source.vue
│   │   │       │   │   ├── analytics-visits.vue
│   │   │       │   │   └── index.vue
│   │   │       │   └── workspace/
│   │   │       │       └── index.vue
│   │   │       ├── demos/
│   │   │       │   ├── access/
│   │   │       │   │   ├── admin-visible.vue
│   │   │       │   │   ├── button-control.vue
│   │   │       │   │   ├── index.vue
│   │   │       │   │   ├── menu-visible-403.vue
│   │   │       │   │   ├── super-visible.vue
│   │   │       │   │   └── user-visible.vue
│   │   │       │   ├── active-icon/
│   │   │       │   │   └── index.vue
│   │   │       │   ├── badge/
│   │   │       │   │   └── index.vue
│   │   │       │   ├── breadcrumb/
│   │   │       │   │   ├── lateral-detail.vue
│   │   │       │   │   ├── lateral.vue
│   │   │       │   │   └── level-detail.vue
│   │   │       │   ├── features/
│   │   │       │   │   ├── clipboard/
│   │   │       │   │   │   └── index.vue
│   │   │       │   │   ├── file-download/
│   │   │       │   │   │   ├── base64.ts
│   │   │       │   │   │   └── index.vue
│   │   │       │   │   ├── full-screen/
│   │   │       │   │   │   └── index.vue
│   │   │       │   │   ├── hide-menu-children/
│   │   │       │   │   │   ├── children.vue
│   │   │       │   │   │   └── parent.vue
│   │   │       │   │   ├── icons/
│   │   │       │   │   │   └── index.vue
│   │   │       │   │   ├── json-bigint/
│   │   │       │   │   │   └── index.vue
│   │   │       │   │   ├── login-expired/
│   │   │       │   │   │   └── index.vue
│   │   │       │   │   ├── menu-query/
│   │   │       │   │   │   └── index.vue
│   │   │       │   │   ├── new-window/
│   │   │       │   │   │   └── index.vue
│   │   │       │   │   ├── request-params-serializer/
│   │   │       │   │   │   └── index.vue
│   │   │       │   │   ├── tabs/
│   │   │       │   │   │   ├── index.vue
│   │   │       │   │   │   └── tab-detail.vue
│   │   │       │   │   ├── vue-query/
│   │   │       │   │   │   ├── concurrency-caching.vue
│   │   │       │   │   │   ├── index.vue
│   │   │       │   │   │   ├── infinite-queries.vue
│   │   │       │   │   │   ├── paginated-queries.vue
│   │   │       │   │   │   ├── query-retries.vue
│   │   │       │   │   │   └── typing.ts
│   │   │       │   │   └── watermark/
│   │   │       │   │       └── index.vue
│   │   │       │   └── nested/
│   │   │       │       ├── menu-1.vue
│   │   │       │       ├── menu-2-1.vue
│   │   │       │       ├── menu-3-1.vue
│   │   │       │       └── menu-3-2-1.vue
│   │   │       ├── examples/
│   │   │       │   ├── button-group/
│   │   │       │   │   └── index.vue
│   │   │       │   ├── captcha/
│   │   │       │   │   ├── point-selection-captcha.vue
│   │   │       │   │   ├── slider-captcha.vue
│   │   │       │   │   ├── slider-rotate-captcha.vue
│   │   │       │   │   └── slider-translate-captcha.vue
│   │   │       │   ├── count-to/
│   │   │       │   │   └── index.vue
│   │   │       │   ├── doc-button.vue
│   │   │       │   ├── drawer/
│   │   │       │   │   ├── auto-height-demo.vue
│   │   │       │   │   ├── base-demo.vue
│   │   │       │   │   ├── dynamic-demo.vue
│   │   │       │   │   ├── form-drawer-demo.vue
│   │   │       │   │   ├── in-content-demo.vue
│   │   │       │   │   ├── index.vue
│   │   │       │   │   └── shared-data-demo.vue
│   │   │       │   ├── ellipsis/
│   │   │       │   │   └── index.vue
│   │   │       │   ├── form/
│   │   │       │   │   ├── api.vue
│   │   │       │   │   ├── basic.vue
│   │   │       │   │   ├── custom-layout.vue
│   │   │       │   │   ├── custom.vue
│   │   │       │   │   ├── dynamic.vue
│   │   │       │   │   ├── merge.vue
│   │   │       │   │   ├── modules/
│   │   │       │   │   │   └── two-fields.vue
│   │   │       │   │   ├── query.vue
│   │   │       │   │   ├── rules.vue
│   │   │       │   │   └── scroll-to-error-test.vue
│   │   │       │   ├── json-viewer/
│   │   │       │   │   ├── data.ts
│   │   │       │   │   └── index.vue
│   │   │       │   ├── layout/
│   │   │       │   │   └── col-page.vue
│   │   │       │   ├── loading/
│   │   │       │   │   └── index.vue
│   │   │       │   ├── modal/
│   │   │       │   │   ├── auto-height-demo.vue
│   │   │       │   │   ├── base-demo.vue
│   │   │       │   │   ├── blur-demo.vue
│   │   │       │   │   ├── drag-demo.vue
│   │   │       │   │   ├── dynamic-demo.vue
│   │   │       │   │   ├── form-modal-demo.vue
│   │   │       │   │   ├── in-content-demo.vue
│   │   │       │   │   ├── index.vue
│   │   │       │   │   ├── nested-demo.vue
│   │   │       │   │   └── shared-data-demo.vue
│   │   │       │   ├── motion/
│   │   │       │   │   └── index.vue
│   │   │       │   ├── resize/
│   │   │       │   │   └── basic.vue
│   │   │       │   ├── tippy/
│   │   │       │   │   └── index.vue
│   │   │       │   └── vxe-table/
│   │   │       │       ├── basic.vue
│   │   │       │       ├── custom-cell.vue
│   │   │       │       ├── edit-cell.vue
│   │   │       │       ├── edit-row.vue
│   │   │       │       ├── fixed.vue
│   │   │       │       ├── form.vue
│   │   │       │       ├── remote.vue
│   │   │       │       ├── table-data.ts
│   │   │       │       ├── tree.vue
│   │   │       │       └── virtual.vue
│   │   │       └── system/
│   │   │           ├── dept/
│   │   │           │   ├── data.ts
│   │   │           │   ├── list.vue
│   │   │           │   └── modules/
│   │   │           │       └── form.vue
│   │   │           ├── menu/
│   │   │           │   ├── data.ts
│   │   │           │   ├── list.vue
│   │   │           │   └── modules/
│   │   │           │       └── form.vue
│   │   │           └── role/
│   │   │               ├── data.ts
│   │   │               ├── list.vue
│   │   │               └── modules/
│   │   │                   └── form.vue
│   │   ├── tailwind.config.mjs
│   │   ├── tsconfig.json
│   │   ├── tsconfig.node.json
│   │   └── vite.config.mts
│   ├── pnpm-workspace.yaml
│   ├── scripts/
│   │   ├── clean.mjs
│   │   ├── deploy/
│   │   │   ├── Dockerfile
│   │   │   ├── build-local-docker-image.sh
│   │   │   └── nginx.conf
│   │   ├── turbo-run/
│   │   │   ├── README.md
│   │   │   ├── bin/
│   │   │   │   └── turbo-run.mjs
│   │   │   ├── build.config.ts
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── index.ts
│   │   │   │   └── run.ts
│   │   │   └── tsconfig.json
│   │   └── vsh/
│   │       ├── README.md
│   │       ├── bin/
│   │       │   └── vsh.mjs
│   │       ├── build.config.ts
│   │       ├── package.json
│   │       ├── src/
│   │       │   ├── check-circular/
│   │       │   │   └── index.ts
│   │       │   ├── check-dep/
│   │       │   │   └── index.ts
│   │       │   ├── code-workspace/
│   │       │   │   └── index.ts
│   │       │   ├── index.ts
│   │       │   ├── lint/
│   │       │   │   └── index.ts
│   │       │   └── publint/
│   │       │       └── index.ts
│   │       └── tsconfig.json
│   ├── stylelint.config.mjs
│   ├── tea.yaml
│   ├── turbo.json
│   ├── vben-admin.code-workspace
│   ├── vitest.config.ts
│   └── vitest.workspace.ts
├── hiauth-server/
│   ├── pom.xml
│   └── src/
│       ├── main/
│       │   ├── java/
│       │   │   └── cn/
│       │   │       └── hiauth/
│       │   │           └── server/
│       │   │               ├── ServerStarter.java
│       │   │               ├── api/
│       │   │               │   ├── dto/
│       │   │               │   │   ├── KeywordPageUserDto.java
│       │   │               │   │   ├── PageDepDto.java
│       │   │               │   │   ├── PageEmpDto.java
│       │   │               │   │   ├── PageRoleDto.java
│       │   │               │   │   ├── RegisterDto.java
│       │   │               │   │   ├── app/
│       │   │               │   │   │   ├── AppCreateDto.java
│       │   │               │   │   │   ├── AppLimitDto.java
│       │   │               │   │   │   ├── AppPageDto.java
│       │   │               │   │   │   └── AppUpdateDto.java
│       │   │               │   │   ├── appClient/
│       │   │               │   │   │   ├── AppClientCreateDto.java
│       │   │               │   │   │   ├── AppClientDeleteDto.java
│       │   │               │   │   │   ├── AppClientLimitDto.java
│       │   │               │   │   │   ├── AppClientPageDto.java
│       │   │               │   │   │   └── AppClientUpdateDto.java
│       │   │               │   │   ├── appResource/
│       │   │               │   │   │   ├── AppResourceCreateDto.java
│       │   │               │   │   │   ├── AppResourcePageDto.java
│       │   │               │   │   │   ├── AppResourceUpdateDto.java
│       │   │               │   │   │   └── FindAppResourceIdsByRoleAndAppDto.java
│       │   │               │   │   ├── corp/
│       │   │               │   │   │   ├── CorpCreateDto.java
│       │   │               │   │   │   ├── CorpPageDto.java
│       │   │               │   │   │   └── CorpUpdateDto.java
│       │   │               │   │   ├── dep/
│       │   │               │   │   │   ├── DepCreateDto.java
│       │   │               │   │   │   ├── DepLimitDto.java
│       │   │               │   │   │   ├── DepPageDto.java
│       │   │               │   │   │   └── DepUpdateDto.java
│       │   │               │   │   ├── dict/
│       │   │               │   │   │   ├── DictCreateDto.java
│       │   │               │   │   │   ├── DictLimitDto.java
│       │   │               │   │   │   ├── DictPageDto.java
│       │   │               │   │   │   └── DictUpdateDto.java
│       │   │               │   │   ├── emp/
│       │   │               │   │   │   ├── EmpCreateDto.java
│       │   │               │   │   │   ├── EmpPageDto.java
│       │   │               │   │   │   └── EmpUpdateDto.java
│       │   │               │   │   ├── login/
│       │   │               │   │   │   ├── CaptchaVerifyDto.java
│       │   │               │   │   │   ├── SmsCodeDto.java
│       │   │               │   │   │   └── SmsCodeLoginDto.java
│       │   │               │   │   ├── role/
│       │   │               │   │   │   ├── RoleAuthDto.java
│       │   │               │   │   │   ├── RoleCreateDto.java
│       │   │               │   │   │   ├── RoleLimitDto.java
│       │   │               │   │   │   ├── RolePageDto.java
│       │   │               │   │   │   └── RoleUpdateDto.java
│       │   │               │   │   └── user/
│       │   │               │   │       ├── UserCreateDto.java
│       │   │               │   │       ├── UserLimitDto.java
│       │   │               │   │       ├── UserPageDto.java
│       │   │               │   │       ├── UserPwdUpdateDto.java
│       │   │               │   │       └── UserUpdateDto.java
│       │   │               │   └── vo/
│       │   │               │       ├── CommonTreeNodeVo.java
│       │   │               │       ├── CorpAppVo.java
│       │   │               │       ├── CorpResourceTreeNodeVo.java
│       │   │               │       ├── CorpVo.java
│       │   │               │       ├── CurrentLoginUserVo.java
│       │   │               │       ├── EmpVo.java
│       │   │               │       ├── IndexCorpAppVo.java
│       │   │               │       ├── SysMenuVo.java
│       │   │               │       └── UserVo.java
│       │   │               ├── config/
│       │   │               │   ├── AuthServerConfig.java
│       │   │               │   ├── BeanConfig.java
│       │   │               │   ├── DocConfig.java
│       │   │               │   ├── SecurityConfig.java
│       │   │               │   ├── WebMvcConfig.java
│       │   │               │   ├── props/
│       │   │               │   │   ├── AppProperties.java
│       │   │               │   │   └── WechatProperties.java
│       │   │               │   ├── rest/
│       │   │               │   │   ├── ApiExceptionAdvice.java
│       │   │               │   │   ├── ResourceAccessDeniedHandler.java
│       │   │               │   │   ├── ResourceApi.java
│       │   │               │   │   ├── ResourceAuthenticationEntryPoint.java
│       │   │               │   │   └── security/
│       │   │               │   │       ├── ApiFilter.java
│       │   │               │   │       ├── MySecurityUser.java
│       │   │               │   │       └── ReadonlyFilter.java
│       │   │               │   └── web/
│       │   │               │       ├── auth/
│       │   │               │       │   ├── AuthFailureHandler.java
│       │   │               │       │   ├── AuthGrantedAuthority.java
│       │   │               │       │   ├── AuthGrantedAuthorityDeserializer.java
│       │   │               │       │   ├── AuthGrantedAuthorityMixin.java
│       │   │               │       │   ├── AuthUser.java
│       │   │               │       │   ├── AuthUserDeserializer.java
│       │   │               │       │   ├── AuthUserMixin.java
│       │   │               │       │   ├── CustomAuthUserAttrs.java
│       │   │               │       │   ├── CustomAuthorizationResponseHandler.java
│       │   │               │       │   ├── CustomJdbcRegisteredClientRepository.java
│       │   │               │       │   ├── CustomOidcUserInfoMapper.java
│       │   │               │       │   └── FederatedIdentityIdTokenCustomizer.java
│       │   │               │       └── security/
│       │   │               │           ├── CaptchaFilter.java
│       │   │               │           ├── CustomAuthenticationFailureHandler.java
│       │   │               │           ├── CustomAuthenticationSuccessHandler.java
│       │   │               │           ├── CustomLoginUrlAuthenticationEntryPoint.java
│       │   │               │           ├── MultiAppHttpSessionRequestCache.java
│       │   │               │           ├── MultiAuthUserService.java
│       │   │               │           ├── MultiAuthenticationProvider.java
│       │   │               │           ├── account/
│       │   │               │           │   ├── AccountAuthenticationFilter.java
│       │   │               │           │   ├── AccountAuthenticationProvider.java
│       │   │               │           │   └── AccountAuthenticationToken.java
│       │   │               │           ├── phone/
│       │   │               │           │   ├── SmsCodeAuthenticationFilter.java
│       │   │               │           │   ├── SmsCodeAuthenticationProvider.java
│       │   │               │           │   └── SmsCodeAuthenticationToken.java
│       │   │               │           └── wechat/
│       │   │               │               ├── QrCodeAuthenticationFilter.java
│       │   │               │               ├── QrCodeAuthenticationProvider.java
│       │   │               │               └── QrCodeAuthenticationToken.java
│       │   │               ├── controller/
│       │   │               │   ├── AuthConsentController.java
│       │   │               │   ├── IndexController.java
│       │   │               │   ├── LoginController.java
│       │   │               │   ├── OauthController.java
│       │   │               │   ├── TestController.java
│       │   │               │   ├── UnpController.java
│       │   │               │   ├── adminspace/
│       │   │               │   │   ├── CorpMgrController.java
│       │   │               │   │   └── UserMgrController.java
│       │   │               │   ├── common/
│       │   │               │   │   ├── AppMgrController.java
│       │   │               │   │   ├── AppResourceMgrController.java
│       │   │               │   │   └── CommonController.java
│       │   │               │   └── corpspace/
│       │   │               │       ├── AppClientMgrController.java
│       │   │               │       ├── DepMgrController.java
│       │   │               │       ├── DictMgrController.java
│       │   │               │       ├── EmpMgrController.java
│       │   │               │       └── RoleMgrController.java
│       │   │               ├── entity/
│       │   │               │   ├── App.java
│       │   │               │   ├── AppResource.java
│       │   │               │   ├── AuthorizationConsent.java
│       │   │               │   ├── Corp.java
│       │   │               │   ├── CorpApp.java
│       │   │               │   ├── CorpAppInfo.java
│       │   │               │   ├── Department.java
│       │   │               │   ├── Dict.java
│       │   │               │   ├── Employee.java
│       │   │               │   ├── File.java
│       │   │               │   ├── Oauth2Authorization.java
│       │   │               │   ├── Oauth2AuthorizationConsent.java
│       │   │               │   ├── Oauth2RegisteredClient.java
│       │   │               │   ├── Role.java
│       │   │               │   ├── RoleAppResource.java
│       │   │               │   ├── SysLog.java
│       │   │               │   └── User.java
│       │   │               ├── mapper/
│       │   │               │   ├── AppMapper.java
│       │   │               │   ├── AppResourceMapper.java
│       │   │               │   ├── CorpAppMapper.java
│       │   │               │   ├── CorpMapper.java
│       │   │               │   ├── DepartmentMapper.java
│       │   │               │   ├── DictMapper.java
│       │   │               │   ├── EmployeeMapper.java
│       │   │               │   ├── FileMapper.java
│       │   │               │   ├── Oauth2AuthorizationConsentMapper.java
│       │   │               │   ├── Oauth2AuthorizationMapper.java
│       │   │               │   ├── Oauth2RegisteredClientMapper.java
│       │   │               │   ├── RoleAppResourceMapper.java
│       │   │               │   ├── RoleMapper.java
│       │   │               │   ├── SysLogMapper.java
│       │   │               │   └── UserMapper.java
│       │   │               ├── service/
│       │   │               │   ├── AppResourceService.java
│       │   │               │   ├── AppService.java
│       │   │               │   ├── CorpAppService.java
│       │   │               │   ├── CorpService.java
│       │   │               │   ├── DepartmentService.java
│       │   │               │   ├── DictService.java
│       │   │               │   ├── EmployeeService.java
│       │   │               │   ├── FileService.java
│       │   │               │   ├── Oauth2AuthorizationConsentService.java
│       │   │               │   ├── Oauth2AuthorizationService.java
│       │   │               │   ├── Oauth2RegisteredClientService.java
│       │   │               │   ├── RoleService.java
│       │   │               │   ├── SimpleSecurityService.java
│       │   │               │   ├── SysLogService.java
│       │   │               │   ├── UserService.java
│       │   │               │   └── impl/
│       │   │               │       ├── AppResourceServiceImpl.java
│       │   │               │       ├── AppServiceImpl.java
│       │   │               │       ├── CorpAppServiceImpl.java
│       │   │               │       ├── CorpServiceImpl.java
│       │   │               │       ├── DepartmentServiceImpl.java
│       │   │               │       ├── DictServiceImpl.java
│       │   │               │       ├── EmployeeServiceImpl.java
│       │   │               │       ├── FileServiceImpl.java
│       │   │               │       ├── Oauth2AuthorizationConsentServiceImpl.java
│       │   │               │       ├── Oauth2AuthorizationServiceImpl.java
│       │   │               │       ├── Oauth2RegisteredClientServiceImpl.java
│       │   │               │       ├── RoleServiceImpl.java
│       │   │               │       ├── SysLogServiceImpl.java
│       │   │               │       └── UserServiceImpl.java
│       │   │               └── utils/
│       │   │                   ├── AliyunSmsUtils.java
│       │   │                   ├── AppResourceUtils.java
│       │   │                   ├── Constant.java
│       │   │                   ├── DateTimeUtils.java
│       │   │                   ├── DepartmentUtils.java
│       │   │                   ├── Oauth2RegisteredClientUtils.java
│       │   │                   ├── RsaUtils.java
│       │   │                   ├── SmsUtils.java
│       │   │                   └── jose/
│       │   │                       ├── Jwks.java
│       │   │                       └── KeyGeneratorUtils.java
│       │   └── resources/
│       │       ├── application-common.yml
│       │       ├── application-doc.yml
│       │       ├── application-hiauth.yml
│       │       ├── application-mybatis.yml
│       │       ├── application-redis.yml
│       │       ├── application.yml
│       │       ├── logback.xml
│       │       ├── mapper/
│       │       │   ├── AppMapper.xml
│       │       │   ├── AppResourceMapper.xml
│       │       │   ├── CorpAppMapper.xml
│       │       │   ├── CorpMapper.xml
│       │       │   ├── DepartmentMapper.xml
│       │       │   ├── DictMapper.xml
│       │       │   ├── EmployeeMapper.xml
│       │       │   ├── FileMapper.xml
│       │       │   ├── Oauth2AuthorizationConsentMapper.xml
│       │       │   ├── Oauth2AuthorizationMapper.xml
│       │       │   ├── Oauth2RegisteredClientMapper.xml
│       │       │   ├── RoleMapper.xml
│       │       │   ├── SysLogMapper.xml
│       │       │   └── UserMapper.xml
│       │       ├── static/
│       │       │   ├── bootstrap-5.3.0/
│       │       │   │   ├── css/
│       │       │   │   │   ├── bootstrap.min.css
│       │       │   │   │   ├── bootstrap.min.css.map
│       │       │   │   │   ├── bootstrap.rtl.min.css
│       │       │   │   │   └── bootstrap.rtl.min.css.map
│       │       │   │   └── js/
│       │       │   │       ├── bootstrap.bundle.min.js
│       │       │   │       └── bootstrap.bundle.min.js.map
│       │       │   ├── css/
│       │       │   │   ├── all.min.css
│       │       │   │   ├── common.css
│       │       │   │   ├── fontawesome.min.css
│       │       │   │   ├── index.css
│       │       │   │   ├── jquery.treetable.css
│       │       │   │   ├── jquery.treetable.theme.default.css
│       │       │   │   ├── login.css
│       │       │   │   ├── login1.css
│       │       │   │   ├── login2.css
│       │       │   │   ├── login3.css
│       │       │   │   ├── navbar.css
│       │       │   │   └── user_me.css
│       │       │   ├── fontawesome-5.15.4/
│       │       │   │   └── css/
│       │       │   │       ├── all.css
│       │       │   │       ├── all.min.css
│       │       │   │       ├── brands.css
│       │       │   │       ├── brands.min.css
│       │       │   │       ├── fontawesome.css
│       │       │   │       ├── fontawesome.min.css
│       │       │   │       ├── regular.css
│       │       │   │       ├── regular.min.css
│       │       │   │       ├── solid.css
│       │       │   │       ├── solid.min.css
│       │       │   │       ├── svg-with-js.css
│       │       │   │       ├── svg-with-js.min.css
│       │       │   │       ├── v4-shims.css
│       │       │   │       └── v4-shims.min.css
│       │       │   ├── img/
│       │       │   │   └── logo.psd
│       │       │   └── js/
│       │       │       ├── depTree.js
│       │       │       ├── jquery.min.js
│       │       │       ├── jquery.treetable.js
│       │       │       ├── jquery.validate.min.js
│       │       │       ├── login.js
│       │       │       ├── particle.js
│       │       │       ├── sliderCaptcha.js
│       │       │       └── wxLogin.js
│       │       └── templates/
│       │           ├── common/
│       │           │   └── include.html
│       │           ├── consent.html
│       │           ├── consent_bak.html
│       │           ├── error/
│       │           │   ├── 401.html
│       │           │   ├── 403.html
│       │           │   ├── 404.html
│       │           │   ├── 500.html
│       │           │   └── unconsent.html
│       │           ├── index.html
│       │           ├── login.html
│       │           ├── login1.html
│       │           ├── login2.html
│       │           ├── login3.html
│       │           ├── oauth/
│       │           │   ├── oauth_approval.html
│       │           │   └── oauth_error.html
│       │           ├── profile.html
│       │           ├── setting.html
│       │           └── user/
│       │               ├── detail.html
│       │               ├── list.html
│       │               ├── me.html
│       │               └── user.html
│       └── test/
│           └── java/
│               └── cn/
│                   └── hiauth/
│                       └── server/
│                           ├── AuthServerTests.java
│                           ├── CustomJdbcRegisteredClientRepositoryTests.java
│                           ├── DefaultAuthorizationServerApplicationTests.java
│                           ├── DefaultAuthorizationServerConsentTests.java
│                           └── service/
│                               ├── AppResourceServiceTests.java
│                               ├── AppServiceTests.java
│                               ├── CorpServiceTests.java
│                               ├── DepartmentServiceTests.java
│                               ├── DictServiceTests.java
│                               ├── EmployeeServiceTests.java
│                               ├── FileServiceTests.java
│                               ├── Oauth2AuthorizationConsentServiceTests.java
│                               ├── Oauth2AuthorizationServiceTests.java
│                               ├── Oauth2RegisteredClientServiceTests.java
│                               ├── RoleServiceTests.java
│                               ├── SysLogServiceTests.java
│                               └── UserServiceTests.java
├── other/
│   └── hiauth.sql
└── pom.xml

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/workflows/deploy.yml
================================================
name: Deploy Docs Pages

on:
  push:
    #分支名字
    branches: [master]

# 设置tokenn访问权限
permissions:
  contents: read
  pages: write
  id-token: write

# 只允许同时进行一次部署,跳过正在运行和最新队列之间的运行队列
# 但是,不要取消正在进行的运行,因为我们希望允许这些生产部署完成
concurrency:
  group: pages
  cancel-in-progress: false

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0 # 如果未启用 lastUpdated,则不需要
      - name: Setup pnpm
        uses: pnpm/action-setup@v2 # 安装pnpm并添加到环境变量
        with:
          version: 10.10.0 # 指定 pnpm 版本
      - name: Setup Pages
        uses: actions/configure-pages@v4  # 在工作流程自动配置GithubPages
      - name: Install dependencies
        run: |
          cd docs
          pnpm install # 安装依赖
      - name: Build with VitePress
        run: |
          cd docs
          pnpm run build # 启动项目
          touch .vitepress/dist/.nojekyll  # 通知githubpages不要使用Jekyll处理这个站点
      - name: Upload artifact
        uses: actions/upload-pages-artifact@v3  # 上传构建产物
        with:
          path: docs/.vitepress/dist # 指定上传的路径

  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }} # 从后续的输出中获取部署后的页面URL
    needs: build    # 在build后面完成
    runs-on: ubuntu-latest  # 运行在最新版本的ubuntu系统上
    name: Deploy
    steps:
      - name: Deploy to GitHub Pages
        id: deployment  # 指定id
        uses: actions/deploy-pages@v4 # 将之前的构建产物部署到github pages中

================================================
FILE: .gitignore
================================================
HELP.md
target/
target/*
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**
!**/src/test/**
*.pdf

### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache

### IntelliJ IDEA ###
.idea
*.ipr
*.iws
*.iml
**/.idea
**/*.iml
rebel.xml

### IntelliJ IDEA Local ###
target
*.log
*.log.*
logs
.DS_Store

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/

### VS Code ###
.vscode/
/logs/

**/node_modules
**/.umi
temp

### java ###
*.class

/docs/.vitepress/dist
/docs/.vitepress/cache
/docs/package-lock.json
/docs/pnpm-lock.yaml

lefthook.yml

================================================
FILE: LICENSE
================================================
 
MIT License (MIT)

Copyright © 2025 HiAuth

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 
associated documentation files (the “Software”), to deal in the Software without restriction, 
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial 
portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.



================================================
FILE: README.md
================================================
<h1 align="center">Hi Auth</h1>

<div align="center">

HiAuth是一个开源的基于OAuth2.0协议的认证、授权系统,除了标准的OAuth2.0授权流程功能外,还提供了应用管理、用户管理、权限管理等相关功能。

[![Star](https://img.shields.io/github/stars/bestaone/HiAuth?color=42b883&logo=github&style=flat-square)](https://github.com/bestaone/HiAuth/stargazers)
[![Fork](https://img.shields.io/github/forks/bestaone/HiAuth?color=42b883&logo=github&style=flat-square)](https://github.com/bestaone/HiAuth/network/members)
[![Language](https://img.shields.io/badge/%E8%AF%AD%E8%A8%80-Java%20%7C%20Springboot%20%7C%20Vue3-red?style=flat-square&color=42b883)](https://github.com/bestaone/HiAuth)
[![License](https://img.shields.io/github/license/bestaone/HiAuth?color=42b883&style=flat-square)](https://github.com/bestaone/HiAuth/blob/master/LICENSE)
[![Author](https://img.shields.io/badge/作者-码道功臣-orange.svg)](https://github.com/bestaone)

</div>

## 介绍
除了认证相关功能外,还提供了`/example/demo`、`/example/himall`项目,供用户参考如何集成。

- 参考`demo`实例,你可以几分钟之内快速验证如何集成HiAuth;
- 参考`himall`实例,你可以快速的启动一个带页面的实例;

### LIVE
- HiAuth Docs:http://docs.hiauth.cn
- HiAuth Admin:http://auth.hiauth.cn/admin
- HiAuth 授权页:http://auth.hiauth.cn

### 目录结构
```
├─cicd                              持续集成
├─docs                              开发文档
├─example                           样例
│ ├─demo                            基础样例
│ ├─hiauth-client                   使用hiauth-client-spring-boot-starter集成hiauth的样例
│ ├─hiauth-client-exp               hiauth-client的简易版,用于做实验
│ ├─hiauth-server-exp               hiauth-server的简易版,用于做实验
│ ├─himall                          带有页面的样例
│ ├─resource                        资源服务样例
│ ├─spring-cloud                    spring-cloud微服务集成样例,原生集成
│ ├─spring-cloud-with-hiauth-client spring-cloud微服务集成样例,使用starter集成
│ ├─wechat-login                    微信登录样例
├─hiauth-client-starter             hiauth-client SDK
│ ├─hiauth-client-commons                       基础包
│ ├─hiauth-client-spring-boot-starter           适用于SpringBoot直接集成
│ ├─hiauth-client-session-spring-boot-starter   SpringCloud架构中,业务服务中的session管理SDK
│ ├─hiauth-client-spring-cloud-gateway-starter  SpringCloudGateway中集成认证授权
├─hiauth-front                      管理端前端项目
├─hiauth-server                     HiAuth服务端
├─other                             其他内容,数据库脚本等
```
## 效果图
- 认证中心登录页
<p align="center">
  <img width="900" src="https://hiauth.oss-cn-zhangjiakou.aliyuncs.com/github/%E8%AE%A4%E8%AF%81%E7%99%BB%E5%BD%95%E9%A1%B5.jpg">
</p>

<p align="center">
  <img width="900" src="https://hiauth.oss-cn-zhangjiakou.aliyuncs.com/github/wechat_login.jpg">
</p>

- 管理后台登录页
<p align="center">
  <img width="900" src="https://hiauth.oss-cn-zhangjiakou.aliyuncs.com/github/%E7%AE%A1%E7%90%86%E5%90%8E%E5%8F%B0%E7%99%BB%E5%BD%95%E9%A1%B5.jpg">
</p>

- 超级管理员-用户管理页
<p align="center">
  <img width="900" src="https://hiauth.oss-cn-zhangjiakou.aliyuncs.com/github/%E8%B6%85%E7%BA%A7%E7%AE%A1%E7%90%86%E5%91%98-%E7%94%A8%E6%88%B7%E7%AE%A1%E7%90%86%E9%A1%B5.jpg">
</p>

- 企业管理员-部门列表页
<p align="center">
  <img width="900" src="https://hiauth.oss-cn-zhangjiakou.aliyuncs.com/github/%E4%BC%81%E4%B8%9A%E7%AE%A1%E7%90%86%E5%91%98-%E9%83%A8%E9%97%A8%E5%88%97%E8%A1%A8%E9%A1%B5.jpg">
</p>

- 企业管理员-员工列表页
<p align="center">
  <img width="900" src="https://hiauth.oss-cn-zhangjiakou.aliyuncs.com/github/%E4%BC%81%E4%B8%9A%E7%AE%A1%E7%90%86%E5%91%98-%E5%91%98%E5%B7%A5%E5%88%97%E8%A1%A8%E9%A1%B5.jpg">
</p>

**如果你觉得此项目对你有帮助,请给我点个star,谢谢!**

## 快速尝试

### 环境要求
- Git
- JDK17+
- Maven 3.8+

### 下载源码
```sh
$ git clone https://github.com/bestaone/HiAuth.git
```
### 构建、启动
```sh
# 启动himall实例
$ cd HiAuth/example/himall
$ mvn clean install
$ mvn spring-boot:run
```

### 验证

- 访问HiMall:http://127.0.0.1:9000 点击`Login`按钮,登录账号:`corpadmin/123456`

> 注意:`127.0.0.1`不能使用`localhost`代替,因为数据库中配置了回调地址为`http://127.0.0.1:9000`。

## 认证模式

**authorization_code模式:**
- 访问授权端点获取`授权码`: http://auth.hiauth.cn/oauth2/authorize?response_type=code&client_id=himall&scope=openid%20profile&redirect_uri=http://127.0.0.1:9000/login/oauth2/code/hiauth-code
- 用户登录并授权后,重定向到`redirect_uri`并附带`授权码`,如下(注意:浏览器开发模式下,网络控制台中,url的参数code值):
```shell
http://127.0.0.1:9000/login/oauth2/code/hiauth-code?code=R4vhO65LvdsNqQ9A3KHwjb...
```
- 使用`授权码`换取访问`令牌`
```shell
# 最后的YourCode替换为上面步骤获取的授权码
$ curl --location --request POST 'http://auth.hiauth.cn/oauth2/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Authorization: Basic aGltYWxsOnNlY3JldA==' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'redirect_uri=http://127.0.0.1:9000/login/oauth2/code/hiauth-code' \
--data-urlencode 'code=YourCode'

# 或者
$ curl --location --request POST 'http://auth.hiauth.cn/oauth2/token' \
--header 'Content-Type: application/x-www-form-urlencoded;charset=UTF-8' \
--header 'Authorization: Basic aGltYWxsOnNlY3JldA==' \
--data 'grant_type=authorization_code&redirect_uri=http://127.0.0.1:9000/login/oauth2/code/hiauth-code&client_id=himall&client_secret=secret&code=YourCode'
```
> 上述“Authorization: Basic aGltYWxsOnNlY3JldA==”中的值“aGltYWxsOnNlY3JldA==”,
> 计算方式为:Base64.encode(client_id:client_secret),
> 例如:client_id=himall,client_secret=secret时,base64解码为:Base64.encode("himall:secret")

返回结果:
```json
{
    "access_token": "eyJraWQiOiJkZTYxMjVmNi0wYTQ5LTQwMGYtYWMzMC02M2U2Zm",
    "refresh_token": "8WS6liiSW0gmUy8yudFAPIHGor3Hf6yBtaBTUNjj3-q9y4JXRlBZ",
    "scope": "openid profile",
    "token_type": "Bearer",
    "expires_in": 35999
}
```

<p align="center">
  <img width="900" src="https://hiauth.oss-cn-zhangjiakou.aliyuncs.com/github/hiauth-1.jpg">
</p>

**client_credentials模式:**
```shell
$ curl --location --request POST 'http://auth.hiauth.cn/oauth2/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'client_id=himall' \
--data-urlencode 'client_secret=secret' \
--data-urlencode 'scope=profile'

# 或者
$ curl --location --request POST 'http://auth.hiauth.cn/oauth2/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data 'grant_type=client_credentials&client_id=himall&client_secret=secret&scope=profile'
```
返回结果:
```json
{
  "access_token": "eyJraWQiOiJkZTYxMjVmNi0wYTQ5LTQwMGYtYWMzMC02M2U2Zm",
  "scope": "profile user",
  "token_type": "Bearer",
  "expires_in": 35999
}
```

**用户信息获取:**
```shell
# 将accessToken替换为上面步骤获取的访问令牌
$ curl --location --request POST 'http://auth.hiauth.cn/userinfo' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer accessToken'
```
> 注意:只在code码模式`grant_type=authorization_code`下生效。

返回结果:
```shell
{
    "sub": "corpadmin",
    "empId": 1,
    "avatarUrl": "/unpapi/image/2c924149ddfe4bd181959ee9bede10c0.jpeg",
    "appId": 91,
    "name": "企业管理员",
    "phoneNum": "13400000001",
    "userId": 11,
    "authorities": [],
    "cid": 1,
    "username": "corpadmin"
}
```

<p align="center">
  <img width="900" src="https://hiauth.oss-cn-zhangjiakou.aliyuncs.com/github/hiauth-2.jpg">
</p>

**scop权限:**
- 在授权请求中包含所需scope
- 获取的访问令牌将包含授予的scope
- 资源服务器验证请求的scope是否匹配
```java
@PreAuthorize("hasAuthority('SCOPE_profile')")
@GetMapping("/protected")
public String protectedResource() {
    return "Accessed protected resource";
}
```

### 其他
- 获取认证服务器配置信息:http://auth.hiauth.cn/.well-known/openid-configuration

### 更多集成方式
- 云端SaaS版集成,[参考文档](http://docs.hiauth.cn/guide/saas);
- 本地Docker版集成,[参考文档](http://docs.hiauth.cn/guide/docker);
- 源码编译安装集成,[参考文档](http://docs.hiauth.cn/guide/sourcecode);

## 社区与作者
<p align="center">
  <img width="900" src="https://hiauth.oss-cn-zhangjiakou.aliyuncs.com/community_wechat.jpg">
</p>

>如果群二维码失效了,请先添加我的微信,然我我拉你入群。

## 授权协议
本项目执行 [MIT](https://github.com/bestaone/HiAuth/blob/master/LICENSE) 协议

================================================
FILE: cicd/Dockerfile
================================================
FROM ubuntu:jdk21-ng-24

# 设置语言
ENV LANG en_US.UTF-8
ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8

# 设置地理位置
ENV TZ=Asia/Shanghai

# 设置时区
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# 安装工具
RUN apt-get update && apt-get install -y curl && apt-get clean

# 挂在目录
VOLUME /data

# 安装jar包
ADD ./hiauth-server/target/hiauth-server.jar /hiauth/app.jar
COPY ./cicd/hiauth.properties /hiauth/conf/hiauth.properties

# 安装前端
ADD ./hiauth-front/apps/web-auth/dist.zip dist.zip
RUN mkdir -p /html && chmod a+rwx -R /html
RUN unzip dist.zip -d /html/admin

# 安装文档
# COPY ./docs/.vitepress/dist /html/docs

# 配置nginx
COPY ./cicd/nginx.conf /etc/nginx/nginx.conf

# 配置启动脚本
RUN echo "#!/bin/bash" > /hiauth/run.sh
RUN echo "java -jar /hiauth/app.jar & nginx -g 'daemon off;'" >> /hiauth/run.sh

# 设置权限
RUN chmod +x /hiauth/run.sh

# 暴露端口
EXPOSE 80 8080

# 设置容器启动时执行的命令
ENTRYPOINT ["/hiauth/run.sh"]

================================================
FILE: cicd/Jenkinsfile
================================================
pipeline {

    agent any

    // 设置环境变量
    environment {
        BUILD_VERSION = sh(script: 'git rev-parse --short HEAD', returnStdout: true).trim()
        CONFIG_FILE = '/var/jenkins_home/hiauth/conf/hiauth.properties'
    }

    // 设置参数, 设置后,构建时会提示填写
//     parameters {
//         string(name: 'DEPLOY_ENV', defaultValue: 'dev', description: 'Environment to deploy to')
//     }

    stages {

        stage('Check Env') {
            steps {
                sh 'echo ${BUILD_VERSION}'
                sh 'docker -v'
                sh 'java -version'
                sh 'mvn -v'
                sh 'node -v'
                sh 'pnpm -v'
            }
        }

        stage('Install') {
            steps {
                sh "mvn clean install -Dmaven.test.skip=false"
                sh "cd hiauth-front && pnpm install --no-frozen-lockfile && pnpm build:auth"
                // sh "cd docs && pnpm install && pnpm run build"
                sh 'docker stop hiauth || true'
                sh 'docker rm -f hiauth || true'
                sh "docker rmi -f bestaone/hiauth:3.0.0 || true"
                sh "docker build -f ./cicd/Dockerfile -t bestaone/hiauth:3.0.0 ."
                sh """
                    docker run -d \
                      --restart=always \
                      -p 9080:80 \
                      -v /opt/install/hiauth/conf:/hiauth/conf \
                      -v /opt/install/hiauth/logs:/hiauth/logs \
                      --name hiauth bestaone/hiauth:3.0.0
                """
            }
        }

    }
}


================================================
FILE: cicd/hiauth.properties
================================================

# login page title, default:
loginPage.title=\u7edf\u4e00\u8ba4\u8bc1\u4e2d\u5fc3
# login page static file name
loginPage.path=login
# login page default username
loginPage.username=corpadmin
# login page default password
loginPage.password=123456
# login page username placeholder
loginPage.usernamePlaceholder=\u4f01\u4e1a\u7ba1\u7406\u5458\uff1acorpadmin\u3001\u7cfb\u7edf\u7ba1\u7406\u5458\uff1aadmin
# login page password placeholder
loginPage.passwordPlaceholder=123456
# login types
loginPage.loginTypes=phone,account,wechat

# aliyun sms
aliyun.sms.accessKeyId=abcdefghi
aliyun.sms.accessKeySecret=jklmnopqrstuvwxyz
aliyun.sms.sign=HiAuth
aliyun.sms.smsTemplateCode=SMS_00000001
aliyun.sms.superSmsCode=888888

# supported wechat qrcode login, config in wx open platform
wechat.open.appid=wx9b04c3f125a24962
wechat.open.appSecret=abcdefghijklmnopqrstuvwxyz
wechat.open.redirectUri=http://127.0.0.1:8080/wechat/doLogin
wechat.open.style=black
wechat.open.href=

# only supported postgresql
datasource.type=com.alibaba.druid.pool.DruidDataSource
datasource.driverClassName=org.postgresql.Driver
datasource.url=jdbc:postgresql://127.0.0.1:5432/hiauth?stringtype=unspecified
datasource.username=test
datasource.password=123456

# redis
redis.host=127.0.0.1
redis.port=6379
redis.database=0
redis.username=
redis.password=

================================================
FILE: cicd/nginx.conf
================================================
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
    worker_connections 768;
    # multi_accept on;
}

http {

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    # server_tokens off;

    # server_names_hash_bucket_size 64;
    # server_name_in_redirect off;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
    ssl_prefer_server_ciphers on;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    gzip on;

    # gzip_vary on;
    # gzip_proxied any;
    # gzip_comp_level 6;
    # gzip_buffers 16 8k;
    # gzip_http_version 1.1;
    # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    server {

        listen 80;

        # hiauth授权服务
        location / {
            proxy_set_header Host $http_host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_pass http://127.0.0.1:8080/;
        }

        # hiauth管理后台静态页面
        location /admin {
            root /html;
            index  index.html index.htm;
            try_files $uri $uri/ /index.html;
        }

        # hiauth管理后台接口服务
        location /gateway/ {
            proxy_set_header Host $http_host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_pass http://127.0.0.1:8080/;
            rewrite "^/gateway/(.*)$" /$1 break;
        }

        # 文档
#        location /docs {
#            root /html;
#            index  index.html index.htm;
#            try_files $uri $uri/ /index.html;
#        }

    }

}


================================================
FILE: docs/.postcssrc.json
================================================
{
  "plugins": {
    "postcss-rtlcss": {
      "ltrPrefix": ":where([dir=\"ltr\"])",
      "rtlPrefix": ":where([dir=\"rtl\"])"
    }
  }
}


================================================
FILE: docs/.vitepress/config/en.ts
================================================
import { createRequire } from 'module'
import { defineConfig, type DefaultTheme } from 'vitepress'

const require = createRequire(import.meta.url)
const pkg = require('../../package.json')

export const en = defineConfig({
  lang: 'en-US',
  description: 'Vite & Vue powered static site generator.',

  themeConfig: {
    nav: nav(),

    sidebar: {
      '/en/guide/': { base: '/en/guide/', items: sidebarGuide() },
      '/en/other/': { base: '/en/other/', items: sidebarOther() }
    },

    editLink: {
      pattern: 'https://github.com/bestaone/HiAuth/edit/main/docs/:path',
      text: 'Edit this page on GitHub'
    },

    footer: {
      message: 'Released under the MIT License.',
      copyright: `Copyright © 2024-${new Date().getFullYear()} Earven`
    }
  }
})

function nav(): DefaultTheme.NavItem[] {
  return [
    {
      text: 'Guide',
      link: '/en/guide/what-is-hiauth',
      activeMatch: '/en/guide/'
    },
    {
      text: 'Other',
      link: '/en/other/support',
      activeMatch: '/en/other/'
    },
    {
      text: pkg.version,
      items: [
        {
          text: 'Changelog',
          link: 'https://github.com/bestaone/HiAuth/blob/main/CHANGELOG.md'
        },
        {
          text: 'Contributing',
          link: 'https://github.com/bestaone/HiAuth/blob/main/.github/contributing.md'
        }
      ]
    }
  ]
}

function sidebarGuide(): DefaultTheme.SidebarItem[] {
  return [
    {
      text: 'Introduction',
      collapsed: false,
      items: [
        { text: 'What is HiAuth', link: 'what-is-hiauth' },
        { text: 'Quick Start', link: 'quick-start' }
      ]
    },
    {
      text: 'Deployment & Integration',
      collapsed: false,
      items: [
        { text: 'SaaS Edition', link: 'saas' },
        { text: 'Docker Edition', link: 'docker' },
        { text: 'Source Code Edition', link: 'sourcecode' },
        { text: 'hiauth-client Integration', link: 'hiauth-client' },
        { text: 'Deploying on K8S', link: 'k8s' },
        { text: 'Integration Testing', link: 'test' }
      ]
    },
    {
      text: 'Secondary Development',
      collapsed: false,
      items: [
        { text: 'Project Structure', link: 'project' },
        { text: 'Front-end Development', link: 'frontend' },
        { text: 'Backend Development', link: 'backend' }
      ]
    },
    {
      text: 'Other',
      collapsed: false,
      items: [
        { text: 'About Topic', link: 'about-topic' },
        { text: 'Issue', link: 'issue' }
      ]
    }
  ]
}

function sidebarOther(): DefaultTheme.SidebarItem[] {
  return [
    {
      text: 'other',
      items: [
        { text: 'support', link: 'support' },
        { text: 'community', link: 'community' }
      ]
    }
  ]
}


================================================
FILE: docs/.vitepress/config/index.ts
================================================
import { defineConfig } from 'vitepress'
import { shared } from './shared'
import { en } from './en'
import { zh } from './zh'

export default defineConfig({
  ...shared,
  locales: {
    root: { label: '简体中文', ...zh },
    en: { label: 'English', ...en }
  }
})


================================================
FILE: docs/.vitepress/config/shared.ts
================================================
import {defineConfig} from 'vitepress'
import {groupIconMdPlugin, groupIconVitePlugin, localIconLoader} from 'vitepress-plugin-group-icons'
import {search as zhSearch} from './zh'

export const shared = defineConfig({
  title: 'HiAuth',
  base: "/",
  rewrites: {
    'zh/:rest*': ':rest*'
  },

  lastUpdated: true,
  cleanUrls: true,
  metaChunk: true,

  markdown: {
    math: true,
    codeTransformers: [
      // We use `[!!code` in demo to prevent transformation, here we revert it back.
      {
        postprocess(code) {
          return code.replace(/\[\!\!code/g, '[!code')
        }
      }
    ],
    config(md) {
      // TODO: remove when https://github.com/vuejs/vitepress/issues/4431 is fixed
      const fence = md.renderer.rules.fence!
      md.renderer.rules.fence = function (tokens, idx, options, env, self) {
        const { localeIndex = 'root' } = env
        const codeCopyButtonTitle = (() => {
          switch (localeIndex) {
            case 'zh':
              return '复制代码'
            case 'en':
              return 'Copy code'
            default:
              return 'Copy code'
          }
        })()
        return fence(tokens, idx, options, env, self).replace(
          '<button title="Copy Code" class="copy"></button>',
          `<button title="${codeCopyButtonTitle}" class="copy"></button>`
        )
      }
      md.use(groupIconMdPlugin)
    }
  },

  sitemap: {
    hostname: 'http://docs.hiauth.cn',
    transformItems(items) {
      return items.filter((item) => !item.url.includes('migration'))
    }
  },

  /* prettier-ignore */
  head: [
    ['link', { rel: 'icon', type: 'image/svg+xml', href: '/hiauth-logo-mini.svg' }],
    ['link', { rel: 'icon', type: 'image/png', href: '/hiauth-logo-mini.png' }],
    ['meta', { name: 'theme-color', content: '#5f67ee' }],
    ['meta', { property: 'og:type', content: 'website' }],
    ['meta', { property: 'og:locale', content: 'zh' }],
    ['meta', { property: 'og:title', content: 'HiAuth | 基于OAuth2.0协议的认证授权服务' }],
    ['meta', { property: 'og:site_name', content: 'VitePress' }],
    ['meta', { property: 'og:image', content: 'https://vitepress.dev/vitepress-og.jpg' }],
    ['meta', { property: 'og:url', content: 'http://docs.hiauth.cn' }],
    ['script', { src: 'https://cdn.usefathom.com/script.js', 'data-site': 'AZBRSFGG', 'data-spa': 'auto', defer: '' }]
  ],

  themeConfig: {
    logo: { src: '/hiauth-logo-mini.svg', width: 24, height: 24 },

    socialLinks: [
      { icon: 'github', link: 'https://github.com/bestaone/HiAuth' }
    ],

    search: {
      provider: 'algolia',
      options: {
        appId: '8J64VVRP8K',
        apiKey: '52f578a92b88ad6abde815aae2b0ad7c',
        indexName: 'vitepress',
        locales: {
          ...zhSearch
        }
      }
    },

    carbonAds: { code: 'CEBDT27Y', placement: 'vuejsorg' }
  },
  vite: {
    plugins: [
      groupIconVitePlugin({
        customIcon: {
          vitepress: localIconLoader(
            import.meta.url,
            '../../public/hiauth-logo-mini.svg'
          ),
          firebase: 'logos:firebase'
        }
      })
    ]
  }
})


================================================
FILE: docs/.vitepress/config/zh.ts
================================================
import { createRequire } from 'module'
import { defineConfig, type DefaultTheme } from 'vitepress'

const require = createRequire(import.meta.url)
const pkg = require('../../package.json')

export const zh = defineConfig({
  lang: 'zh-Hans',
  description: '基于OAuth2.0协议的认证授权服务',

  themeConfig: {
    nav: nav(),

    sidebar: {
      '/guide/': { base: '/guide/', items: sidebarGuide() },
      '/other/': { base: '/other/', items: sidebarOther() }
    },

    editLink: {
      pattern: 'https://github.com/bestaone/HiAuth/edit/main/docs/:path',
      text: '在 GitHub 上编辑此页面'
    },

    footer: {
      message: '基于 MIT 许可发布',
      copyright: `版权所有 © 2024-${new Date().getFullYear()} 张国圣`
    },

    docFooter: {
      prev: '上一页',
      next: '下一页'
    },

    outline: {
      label: '页面导航'
    },

    lastUpdated: {
      text: '最后更新于',
      formatOptions: {
        dateStyle: 'short',
        timeStyle: 'medium'
      }
    },

    langMenuLabel: '多语言',
    returnToTopLabel: '回到顶部',
    sidebarMenuLabel: '菜单',
    darkModeSwitchLabel: '主题',
    lightModeSwitchTitle: '切换到浅色模式',
    darkModeSwitchTitle: '切换到深色模式',
    skipToContentLabel: '跳转到内容'
  }
})

function nav(): DefaultTheme.NavItem[] {
  return [
    {
      text: '文档',
      link: '/guide/what-is-hiauth',
      activeMatch: '/guide/'
    },
    {
      text: '其他',
      link: '/other/support',
      activeMatch: '/other/'
    },
    {
      text: pkg.version,
      items: [
        {
          text: '更新日志',
          link: 'https://github.com/bestaone/HiAuth/blob/main/CHANGELOG.md'
        },
        {
          text: '参与贡献',
          link: 'https://github.com/bestaone/HiAuth/blob/main/.github/contributing.md'
        }
      ]
    }
  ]
}

function sidebarGuide(): DefaultTheme.SidebarItem[] {
  return [
    {
      text: '简介',
      collapsed: false,
      items: [
        { text: '什么是HiAuth', link: 'what-is-hiauth' },
        { text: '快速体验', link: 'quick-start' }
      ]
    },
    {
      text: '部署&集成',
      collapsed: false,
      items: [
        { text: 'SaaS版', link: 'saas' },
        { text: 'Docker版', link: 'docker' },
        { text: '源码版', link: 'sourcecode' },
        { text: 'hiauth-client集成', link: 'hiauth-client' },
        { text: 'K8S上部署', link: 'k8s' },
        { text: '集成测试', link: 'test' }
      ]
    },
    {
      text: '二次开发',
      collapsed: false,
      items: [
        { text: '项目结构', link: 'project' },
        { text: '前端开发', link: 'frontend' },
        { text: '后端开发', link: 'backend' }
      ]
    },
    {
      text: '其他',
      collapsed: false,
      items: [
        { text: '相关资料', link: 'about-topic' },
        { text: '问题', link: 'issue' }
      ]
    }
  ]
}

function sidebarOther(): DefaultTheme.SidebarItem[] {
  return [
    {
      text: '其他',
      items: [
        { text: '技术支持', link: 'support' },
        { text: '社区', link: 'community' }
      ]
    }
  ]
}

export const search: DefaultTheme.AlgoliaSearchOptions['locales'] = {
  zh: {
    placeholder: '搜索文档',
    translations: {
      button: {
        buttonText: '搜索文档',
        buttonAriaLabel: '搜索文档'
      },
      modal: {
        searchBox: {
          resetButtonTitle: '清除查询条件',
          resetButtonAriaLabel: '清除查询条件',
          cancelButtonText: '取消',
          cancelButtonAriaLabel: '取消'
        },
        startScreen: {
          recentSearchesTitle: '搜索历史',
          noRecentSearchesText: '没有搜索历史',
          saveRecentSearchButtonTitle: '保存至搜索历史',
          removeRecentSearchButtonTitle: '从搜索历史中移除',
          favoriteSearchesTitle: '收藏',
          removeFavoriteSearchButtonTitle: '从收藏中移除'
        },
        errorScreen: {
          titleText: '无法获取结果',
          helpText: '你可能需要检查你的网络连接'
        },
        footer: {
          selectText: '选择',
          navigateText: '切换',
          closeText: '关闭',
          searchByText: '搜索提供者'
        },
        noResultsScreen: {
          noResultsText: '无法找到相关结果',
          suggestedQueryText: '你可以尝试查询',
          reportMissingResultsText: '你认为该查询应该有结果?',
          reportMissingResultsLinkText: '点击反馈'
        }
      }
    }
  }
}


================================================
FILE: docs/.vitepress/theme/index.ts
================================================
import Theme from 'vitepress/theme'
import 'virtual:group-icons.css'
import './styles.css'

export default Theme


================================================
FILE: docs/.vitepress/theme/styles.css
================================================
@import url('https://fonts.googleapis.com/css2?family=Vazirmatn:wght@100..900&display=swap');

:root:where(:lang(fa)) {
  --vp-font-family-base:
    'Vazirmatn', 'Inter', ui-sans-serif, system-ui, sans-serif,
    'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
}

:root {
  --vp-home-hero-name-color: transparent;
  --vp-home-hero-name-background: -webkit-linear-gradient(
    120deg,
    #bd34fe 30%,
    #41d1ff
  );
  --vp-home-hero-image-background-image: linear-gradient(
    -45deg,
    #bd34fe 50%,
    #47caff 50%
  );
  --vp-home-hero-image-filter: blur(44px);
}

@media (min-width: 640px) {
  :root {
    --vp-home-hero-image-filter: blur(56px);
  }
}

@media (min-width: 960px) {
  :root {
    --vp-home-hero-image-filter: blur(68px);
  }
}

/* used in reference/default-theme-search */
img[src='/search.png'] {
  width: 100%;
  aspect-ratio: 1 / 1;
}

/* 屏蔽更新时间 */
.last-updated {
  display: none !important;
}

================================================
FILE: docs/en/guide/about-topic.md
================================================
edit...

================================================
FILE: docs/en/guide/backend.md
================================================
edit...

================================================
FILE: docs/en/guide/docker.md
================================================
# Docker Edition {#docker}

The integration process for the Docker edition is similar to the SaaS edition, except that before integration, we need to deploy a Docker version of HiAuth. The local installation and deployment of the Docker edition rely on `PostgreSQL 16+` and `Redis`. If you need to run the HiAuth demo, you will also need a `JDK 17` and `Maven 3.8+` environment.

## Installation and Integration Steps:
- Check the server environment
- Initialize the HiAuth database by executing SQL scripts
- Configure the HiAuth startup configuration file
- Download the image and start the service
- Verify using the HiAuth source code demo

### Check the Server Environment {#check-env}
```shell
# Check the git version
$ git --version
git version 1.8.3.1

# Check the Docker version
$ docker -v
Docker version 26.1.4, build 5650f9b

# Check the JDK version
$ java -version
openjdk version "17.0.5" 2022-10-18

# Check the Maven version
$ mvn -v
Apache Maven 3.8.6 (36645f6c9b5079805ea5009217e36f2cffd34256)
```

### Initialize the HiAuth Database by Executing SQL Scripts {#init-db}
- Install `PostgreSQL 16+`;
- Create a database named `hiauth`;
- Execute the initialization script `HiAuth/other/hiauth.sql`;

### Configure the HiAuth Startup Configuration File {#config-file}
- Create the configuration file `/opt/install/hiauth/conf/hiauth.properties` and configure the correct parameters;
```properties [hiauth.properties]
# login page title, default:
loginPage.title=Welcome Login
# login page static file name
loginPage.path=login
# login page default username
loginPage.username=
# login page default password
loginPage.password=
# login page username placeholder
loginPage.usernamePlaceholder=
# login page password placeholder
loginPage.passwordPlaceholder=
# login types
loginPage.loginTypes=phone,account,wechat

# aliyun sms
aliyun.sms.accessKeyId=abcdefghi
aliyun.sms.accessKeySecret=abcdefghi
aliyun.sms.sign=HiAuth
aliyun.sms.smsTemplateCode=SMS_00000001
aliyun.sms.superSmsCode=888888

# supported wechat qrcode login, config in wx open platform
wechat.open.appid=wx123456789
wechat.open.appSecret=abcdefghijklmnopqrstuvwxyz
wechat.open.redirectUri=http://127.0.0.1:8080/wechat/doLogin
wechat.open.style=black
wechat.open.href=

# only supported postgresql
datasource.type=com.alibaba.druid.pool.DruidDataSource
datasource.driverClassName=org.postgresql.Driver
datasource.url=jdbc:postgresql://db_host:5432/hiauth?stringtype=unspecified
datasource.username=test
datasource.password=123456

# redis
redis.host=redis_host
redis.port=6379
redis.database=0
redis.username=test
redis.password=123456
```
> Configuration reference: [hiauth.properties](https://github.com/bestaone/HiAuth/blob/master/other/hiauth.properties)

### Download the Image and Start the Service {#download-image}
```shell
# You need to be able to access the Docker Hub central repository, which may require a proxy.
$ docker run -d \
  --restart=always \
  -p 9080:80 -p 8080:8080 \
  -v /opt/install/hiauth/conf:/hiauth/conf \
  -v /opt/install/hiauth/logs:/hiauth/logs \
  --name hiauth bestaone/hiauth:3.0.0
  
# If you cannot access the Docker Hub central repository, you can download the image from the Alibaba Cloud repository.
$ docker run -d \
  --restart=always \
  -p 9080:80 -p 8080:8080 \
  -v /opt/install/hiauth/conf:/hiauth/conf \
  -v /opt/install/hiauth/logs:/hiauth/logs \
  --name hiauth registry.cn-zhangjiakou.aliyuncs.com/bestaone/hiauth:3.0.0
  
# Check the images  
$ docker images
REPOSITORY                                                 TAG           IMAGE ID       CREATED         SIZE
bestaone/hiauth                                            3.0.0         c5e4140bd5aa   3 hours ago     810MB
registry-vpc.cn-zhangjiakou.aliyuncs.com/bestaone/hiauth   3.0.0         c5e4140bd5aa   3 hours ago     810MB

# Check the services
$ docker ps
CONTAINER ID   IMAGE                   COMMAND                  CREATED        STATUS       PORTS                                                  NAMES
3ea0fdb8a165   bestaone/hiauth:3.0.0   "/hiauth/run.sh"         3 hours ago    Up 3 hours   8080/tcp, 0.0.0.0:9080->80/tcp, :::9080->80/tcp        hiauth

# Check the logs
$ docker logs 3ea0fdb8a165
...
INFO 7 [main] org.springframework.boot.web.embedded.tomcat.TomcatWebServer Tomcat started on port 8080 (http) with context path '/'
INFO 7 [main] cn.hiauth.server.ServerStarter Started ServerStarter in 10.094 seconds (process running for 11.107)
...

# Access the service
$ curl http://127.0.0.1:9080
{ "code": 50000, "message": "Invalid or expired token" }
```
- The authorization address for the Docker edition of HiAuth is: http://127.0.0.1:9080
- The management address for the Docker edition of HiAuth is: http://127.0.0.1:9080/admin

### Verify Using the HiAuth Source Code Demo {#hiauth-himall}
- Download the source code
```shell
$ git clone https://github.com/bestaone/HiAuth.git
```
- Modify the configuration `HiAuth/example/himall/src/main/resources/application.yml`
```yaml
...
spring.security.oauth2.client:
  provider:
    hiauth-server:
      # Change the value of issuer-uri from http://auth.hiauth.cn to http://127.0.0.1:9080
      issuer-uri: http://auth.hiauth.cn
...
```
- Compile and run
```shell
$ cd HiAuth/example/himall
$ mvn clean install
$ mvn spring-boot:run
```

### Verification
- Open a browser and visit: http://127.0.0.1:9000
- Click the `Login` button, and you will be redirected to the unified authentication system. Enter the account: `corpadmin`, password: `123456`
- After successful login, you will see the home page and the logged-in user information!

## Video Tutorial
<iframe src="//player.bilibili.com/player.html?bvid=BV14hZEYmEEq&page=1" allowfullscreen></iframe>

================================================
FILE: docs/en/guide/frontend.md
================================================
edit...

================================================
FILE: docs/en/guide/hiauth-client.md
================================================
edit...

================================================
FILE: docs/en/guide/issue.md
================================================
edit...

================================================
FILE: docs/en/guide/k8s.md
================================================
edit...

================================================
FILE: docs/en/guide/quick-start.md
================================================
# Quick Start {#quick-start}

## Admin Console {#admin}

Experience it on the [Admin End](http://auth.hiauth.cn/admin).
- **System Administrator Account**: `admin\123456`. This account can view all configurations. By switching tenants, you can view the configurations of the current tenant. To prevent unauthorized changes, this account has read-only access.
- **Corporate Administrator Account**: `corpadmin\123456`. This account can view all configurations within the tenant. To prevent unauthorized changes, this account has read-only access.

## Unified Authentication System {#auth}

Experience the [Authentication End](http://auth.hiauth.cn) for application login authorization. After integrating with third-party applications, you will be redirected to this page for authentication.

## Documentation {#docs}

Get help from the [Documentation](http://hiauth.cn).

================================================
FILE: docs/en/guide/saas.md
================================================
# SaaS Edition {#saas}

To integrate the SaaS edition, users need to sign up for an account on HiAuth, add applications, and perform relevant settings. Then, they can use the obtained `client-id` and `client-secret` for integration. For a quick validation, we will use the demo account provided in the system for integration. After completing the validation, users can replace it with their own account.

- The HiAuth authorization address is: http://auth.hiauth.cn
- The HiAuth management address is: http://auth.hiauth.cn/admin

## Example of Integrating with a SpringBoot Project
- Create a SpringBoot project
- Add dependencies
- Add configurations
- Add a home page

Integration with the SaaS edition can be completed with just these simple steps.

## Running the HiAuth Source Code Demo {#hiauth-demo}
### Environment Requirements
- Git
- JDK 17+
- Maven 3.8+

### Running Script
```shell
# Download HiAuth source code
$ git clone https://github.com/bestaone/HiAuth.git
# Enter the demo directory
$ cd HiAuth/example/himall
# Compile and install
$ mvn clean install
# Run
$ mvn spring-boot:run
```
### Verification
- Open a browser and visit: http://127.0.0.1:9000
- Click the `Login` button, and you will be redirected to the unified authentication system. Enter the account: `corpadmin`, password: `123456`
- After successful login, you will see the home page and the logged-in user information!

## Step-by-Step Integration {#hand-by-hand}
### Environment Requirements
- JDK 17+
- Maven 3.8+

### Create an Empty SpringBoot Project

Use [Spring Initializr](https://start.spring.io/) to create an empty SpringBoot project. The `pom.xml` file is as follows:

```xml [pom.xml]
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
	https://maven.apache.org/xsd/maven-4.0.0.xsd">
    
	<modelVersion>4.0.0</modelVersion>
    
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.4.5</version>
		<relativePath/>
	</parent>
    
	<groupId>cn.hiauth</groupId>
	<artifactId>demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>demo</name>
	<description>Demo project for Spring Boot</description>
    
	<properties>
		<java.version>17</java.version>
	</properties>
    
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>
```

### Add Dependencies
```xml [pom.xml]
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
```

### Add Configurations
```yml [application.yml]
server.port: 9000
spring.security.oauth2.client:
  provider:
    # Authentication server information
    hiauth-server:
      # If you have deployed HiAuth privately, replace this address with the private deployment authentication server address
      issuer-uri: http://auth.hiauth.cn
      authorizationUri: http://auth.hiauth.cn/oauth2/authorize
      # Token acquisition address
      tokenUri: http://auth.hiauth.cn/oauth2/token
      userInfoUri: http://auth.hiauth.cn/userinfo
      jwkSetUri: http://auth.hiauth.cn/oauth2/jwks
      #userNameAttribute: name
  registration:
    hiauth-code:
      # Authentication provider, indicating which authentication server to use for authentication, associated with the above hiauth-server
      provider: hiauth-server
      # Client name
      client-name: himall
      # Client ID, obtained from the authentication platform
      client-id: himall
      # Client secret
      client-secret: secret
      # Client authentication method client_secret_basic\client_secret_post
      client-authentication-method: client_secret_basic
      # Use authorization code mode to obtain token
      authorization-grant-type: authorization_code
      # Callback address after authentication, this address needs to be registered in the oauth2_registered_client table,
      # otherwise the callback will be rejected
      redirect-uri: http://127.0.0.1:9000/login/oauth2/code/hiauth-code
      scope:
        - profile
        - openid
```
> Note: After adding the `application.yml` file, delete the `application.properties` file.

### Add a Controller
```java [IndexController.java]
package cn.hiauth.demo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.annotation.RegisteredOAuth2AuthorizedClient;
import org.springframework.ui.Model;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.Map;

@RestController
public class IndexController {

    private final RestTemplate restTemplate = new RestTemplate();

    @Value("${spring.security.oauth2.client.provider.hiauth-server.userInfoUri}")
    private String userInfoUri;

    @GetMapping("/")
    public Map<?, ?> index(Model model, @RegisteredOAuth2AuthorizedClient OAuth2AuthorizedClient oAuth2AuthorizedClient) {
        // After authentication, the accessToken will be obtained
        String accessToken = oAuth2AuthorizedClient.getAccessToken().getTokenValue();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        // Set the request header and include the accessToken in it
        headers.add("Authorization", "Bearer " + accessToken);
        MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
        HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(map, headers);
        // Request the authentication server to obtain user information
        return restTemplate.postForObject(this.userInfoUri, entity, Map.class);
    }

}
```

### Verification

- Start the project and visit: http://127.0.0.1:9000. The system will detect that you are not logged in and redirect you to the unified authentication system;
- Enter the account: `corpadmin`, password: `123456`. After successful login, you will be redirected back to the application;
- In this demo, the home page directly outputs the logged-in user information in `json` format;
```json
{
  "sub": "corpadmin",
  "empId": 1,
  "avatarUrl": "/unpapi/image/2c924149ddfe4bd181959ee9bede10c0.jpeg",
  "appId": 91,
  "name": "Corporate Administrator",
  "phoneNum": "13400000001",
  "userId": 11,
  "authorities": [],
  "cid": 1,
  "username": "corpadmin"
}
```

## Video Tutorial
<iframe src="//player.bilibili.com/player.html?bvid=BV1KhZEYmEf1&page=1" scrolling="no" allowfullscreen></iframe>

================================================
FILE: docs/en/guide/sourcecode.md
================================================
# Source Code Edition {#sourcecode}
The integration process for the source code edition is similar to the Docker edition, except that the Docker version of HiAuth is replaced with a source code compilation and startup.

## Environment Requirements {#env-demand}
- Git
- JDK 17+
- Maven 3.8+
- Node.js v20.15+
- pnpm 10.10+
- PostgreSQL 16+
- Redis

## Installation and Integration Steps
- Check the server environment
- Download the source code
- Initialize the HiAuth database by executing SQL scripts
- Configure the HiAuth startup configuration file
- Compile the source code and start the service
- Verify using the HiAuth source code demo

### Check the Server Environment {#check-env}
```shell
# Check the git version
$ git --version
git version 1.8.3.1

# Check the JDK version
$ java -version
openjdk version "17.0.5" 2022-10-18

# Check the Maven version
$ mvn -v
Apache Maven 3.8.6 (36645f6c9b5079805ea5009217e36f2cffd34256)

# Check the Node.js version
$ node -v
v20.15.0

# Check the pnpm version
$ pnpm -v
9.14.2
```

### Download the Source Code {#download-source}
```shell
$ git clone https://github.com/bestaone/HiAuth.git
```

### Initialize the HiAuth Database by Executing SQL Scripts {#init-db}
- Install `PostgreSQL 16+`;
- Create a database named `hiauth`;
- Execute the initialization script `HiAuth/other/hiauth.sql`;

### Configure the HiAuth Startup Configuration File {#config-file}
- Modify the configuration file `HiAuth/cicd/hiauth.properties` to your own settings;
```properties [hiauth.properties]
# Only PostgreSQL is supported
datasource.type=com.alibaba.druid.pool.DruidDataSource
datasource.driverClassName=org.postgresql.Driver
datasource.url=jdbc:postgresql://db_host:5432/hiauth
datasource.username=test
datasource.password=123456

redis.host=redis_host
redis.port=6379
redis.database=0
redis.username=test
redis.password=123456
```
- Apply the configuration file by modifying `HiAuth/hiauth-server/src/main/resources/application.yml`;
```yaml
...
# Replace `/hiauth/conf/hiauth.properties` with the file path you configured above
spring.config.import: ${CONFIG_FILE:optional:/hiauth/conf/hiauth.properties}
...
```

### Compile the Source Code and Start the Service {#compile-start}
```shell
# Compile and start the backend service
$ cd HiAuth/hiauth-server
$ mvn clean install
$ mvn spring-boot:run

# Compile and start the frontend service
$ cd HiAuth/hiauth-front
$ pnpm install
$ pnpm dev:auth

# Access the service
$ curl http://127.0.0.1:8080
{ "code": 50000, "message": "Invalid or expired token" }
```
- Check the backend service: http://127.0.0.1:8080
- Check the frontend service: http://127.0.0.1:5666/admin (The port may change, please check the console)

### Verify Using the HiAuth Source Code Demo {#hiauth-himall}
- Modify the configuration `HiAuth/example/himall/src/main/resources/application.yml`
```yaml
...
spring.security.oauth2.client:
  provider:
    hiauth-server:
      # Change the value of issuer-uri from http://auth.hiauth.cn to http://127.0.0.1:8080
      issuer-uri: http://auth.hiauth.cn
...
```
- Compile and run
```shell
$ cd HiAuth/example/himall
$ mvn clean install
$ mvn spring-boot:run
```

### Verification
- Open a browser and visit: http://127.0.0.1:9000
- Click the `Login` button, and you will be redirected to the unified authentication system. Enter the account: `corpadmin`, password: `123456`
- After successful login, you will see the home page and the logged-in user information!

## Video Tutorial
<iframe src="//player.bilibili.com/player.html?bvid=BV1KhZEYmERF&page=1" allowfullscreen></iframe>

================================================
FILE: docs/en/guide/test.md
================================================
edit...

================================================
FILE: docs/en/guide/what-is-hiauth.md
================================================
# What is HiAuth? {#what-is-hiauth}

HiAuth is an authentication and authorization system based on the OAuth2.0 protocol. By integrating the HiAuth system, you can quickly enable authentication and authorization functions for your application. HiAuth supports SaaS mode, Docker private deployment mode, and source code compilation installation mode. Moreover, it is completely free and open-source.

<div class="tip custom-block" style="padding-top: 8px">

Want to give it a try? Jump to [Quick Start](./quick-start).

</div>

## Functions {#function}

### **1. Authentication**
Based on the `OAuth2.0` authorization protocol, it allows third-party applications to access user resources with user authorization, without sharing user credentials.
- **Core Process**:
    - **Authorization Code Mode**: Suitable for web applications, obtaining an access token through an authorization code exchange (most secure).
    - **Implicit Mode**: Suitable for Single Page Applications (SPAs), directly returning an access token (no refresh token).
    - **Password Mode**: Users directly provide their account and password to the client (for use only in trusted scenarios).
    - **Client Credentials Mode**: Applications obtain tokens directly with their own identity (for service-to-service communication).
- **Token Management**:
    - Access Token is used for resource access, with a relatively short validity period.
    - Refresh Token is used to obtain a new access token and must be securely stored.
- **Security**:
    - Enforces HTTPS transmission to prevent token leakage.
    - Token Binding to prevent man-in-the-middle attacks.

### **2. Access Authorization**
Access authorization (`Authorization`) determines whether users/applications can perform specific operations or access resources. It is based on `RBAC` (Role-Based Access Control), assigning permissions through roles (e.g., administrator, regular user).

### **3. Application Management**
Manages the integration and lifecycle of third-party or internal applications.
- **Core Functions**:
    - **Application Registration**: Assigns unique `ClientID`/`ClientSecret`, defining permission scopes.
    - **Key Rotation**: Regularly updates `ClientSecret` to prevent leakage risks.
    - **Permission Control**: Limits the API or data scope that applications can access.
- **Security Auditing**:
    - Logs application behavior (e.g., API call frequency).
    - Reviews application permission requests to ensure the principle of least privilege.

### **4. Organization Management**
Manages the hierarchical structure and member relationships of enterprises or teams.
- **Functions**:
    - **Multi-level Architecture**: Supports nested structures such as departments, teams, and project groups.
    - **Multi-tenancy Support**: Isolates data and permissions of different organizations (e.g., in SaaS scenarios).
    - **Administrator Assignment**: Sets organization administrators to manage members and permissions.

### **5. Permission Management**
Defines and manages the operations that users or roles can perform.
- **Core Mechanism**:
    - **Permission Granularity**: Supports control at the API level, functional level, or data field level.
    - **Permission Groups**: Packages permissions into templates (e.g., "Finance Approval Group").
    - **Permission Inheritance and Overrides**: Sub-roles inherit permissions from parent roles, with the ability to make local adjustments.
- **Audit and Compliance**:
    - Permission change logs: Records who modified permissions and when.
    - Regularly reviews permission assignments to avoid redundancy or excessive authorization.

### **6. User Management**
Manages user identities, authentication, and lifecycle.
- **Core Functions**:
    - **Identity Storage**: Supports local databases.
    - **Lifecycle Management**: User registration, disabling, deletion, and profile updates.
    - **Authentication Enhancement**: Multi-Factor Authentication (MFA), Single Sign-On (SSO).


## Video Tutorial
<iframe src="//player.bilibili.com/player.html?bvid=BV1KhZEYmEU9&page=1" allowfullscreen></iframe>

================================================
FILE: docs/en/index.md
================================================
---
layout: home

title: HiAuth
titleTemplate: Authentication and Authorization Service Based on OAuth2.0 Protocol

hero:
  name: HiAuth
  text: Authentication and Authorization Service Based on OAuth2.0 Protocol
  tagline: With just a few simple steps, you can integrate into your application
  actions:
    - theme: brand
      text: Quick Start ->
      link: /zh/guide/what-is-vitepress
    - theme: alt
      text: Online Preview
      link: http://auth.hiauth.cn
    - theme: alt
      text: GitHub
      link: https://github.com/bestaone/HiAuth
  image:
    src: /hiauth-large.png
    alt: HiAuth

features:
  - icon: 📝
    title: Login authentication
    details: Single sign on, multi login, single end login, mutually exclusive login, no login Multiple login strategies can be configured.
  - icon: 🔐
    title: Rights Management
    details: Permission authentication, role management, permission management, menu management, session management, interface authentication Multiple flexible authentication schemes.
  - icon: 🌐
    title: OAuth2.0 protocol
    details: Authentication service based on OAuth2.0 protocol, supporting four authorization modes for easy integration with different development language environments.
  - icon: 🚀
    title: Out of box
    details: Provide SAAS version, one click deployment Docker version, and source code local deployment version, which can be developed based on source code for secondary development.
---


================================================
FILE: docs/lunaria.config.json
================================================
{
  "$schema": "./node_modules/@lunariajs/core/config.schema.json",
  "repository": {
    "name": "bestaone/HiAuth",
    "rootDir": "docs"
  },
  "files": [
    {
      "location": ".vitepress/config/{en,zh,pt,ru,es,ko,fa}.ts",
      "pattern": ".vitepress/config/@lang.ts",
      "type": "universal"
    },
    {
      "location": "**/*.md",
      "pattern": "@lang/@path",
      "type": "universal"
    }
  ],
  "defaultLocale": {
    "label": "简体中文",
    "lang": "zh"
  },
  "locales": [
    {
      "label": "English",
      "lang": "en"
    }
  ],
  "outDir": ".vitepress/dist/_translations",
  "ignoreKeywords": ["lunaria-ignore"]
}


================================================
FILE: docs/package.json
================================================
{
  "name": "docs",
  "version": "3.0.0",
  "private": true,
  "type": "module",
  "scripts": {
    "dev": "vitepress dev",
    "build": "vitepress build",
    "preview": "vitepress preview",
    "lunaria:build": "lunaria build",
    "lunaria:open": "open-cli .vitepress/dist/_translations/index.html"
  },
  "devDependencies": {
    "@lunariajs/core": "^0.1.1",
    "markdown-it-mathjax3": "^4.3.2",
    "open-cli": "^8.0.0",
    "postcss-rtlcss": "^5.6.0",
    "vitepress": "2.0.0-alpha.3",
    "vitepress-plugin-group-icons": "^1.3.6"
  }
}


================================================
FILE: docs/public/pure.html
================================================
<!doctype html>
<html>
  <head>
    <title>Plain HTML page | VitePress</title>
    <meta charset="utf-8" />
    <meta name="robots" content="noindex, nofollow" />
  </head>
  <body>
    <h1>Not part of the main VitePress docs site</h1>
    <div>This page is plain HTML in the <code>public</code> directory.</div>
  </body>
</html>


================================================
FILE: docs/zh/guide/about-topic.md
================================================
编辑中...

================================================
FILE: docs/zh/guide/backend.md
================================================
编辑中...


================================================
FILE: docs/zh/guide/docker.md
================================================
# Docker版 {#docker}
Docker版的集成过程和SaaS版类似,只不过在集成前,我们需要部署一个Docker版本的HiAuth。Docker版的本地安装部署,依赖`PostgreSQL16+`、`Redis`,如果需要运行HiAuth自带的Demo的话,还需要 `JDK17` 和 `Maven 3.8+`环境。

## 安装及集成步骤:
- 检查服务器环境
- 初始化HiAuth数据库,执行SQL脚本
- 配置HiAuth的启动配置文件
- 下载镜像、启动服务
- 使用HiAuth源码Demo验证

### 检查服务器环境 {#check-env}
```shell
# 检查git版本
$ git --version
git version 1.8.3.1

# 检查daocker版本
$ docker -v
Docker version 26.1.4, build 5650f9b

# 检查JDK版本
$ java -version
openjdk version "17.0.5" 2022-10-18

# 检查maven版本
$ mvn -v
Apache Maven 3.8.6 (36645f6c9b5079805ea5009217e36f2cffd34256)
```

### 初始化HiAuth数据库,执行SQL脚本 {#init-db}
- 安装`PostgreSQL16+`;
- 创建数据库`hiauth`;
- 执行初始化脚本 `HiAuth/other/hiauth.sql` ;

### 配置HiAuth的启动配置文件 {#config-file}
- 创建配置文件 `/opt/install/hiauth/conf/hiauth.properties`,并配置正确的参数;
```properties [hiauth.properties]
# login page title, default:
loginPage.title=Welcome Login
# login page static file name
loginPage.path=login
# login page default username
loginPage.username=
# login page default password
loginPage.password=
# login page username placeholder
loginPage.usernamePlaceholder=
# login page password placeholder
loginPage.passwordPlaceholder=
# login types
loginPage.loginTypes=phone,account,wechat

# aliyun sms
aliyun.sms.accessKeyId=abcdefghi
aliyun.sms.accessKeySecret=abcdefghi
aliyun.sms.sign=HiAuth
aliyun.sms.smsTemplateCode=SMS_00000001
aliyun.sms.superSmsCode=888888

# supported wechat qrcode login, config in wx open platform
wechat.open.appid=wx123456789
wechat.open.appSecret=abcdefghijklmnopqrstuvwxyz
wechat.open.redirectUri=http://127.0.0.1:8080/wechat/doLogin
wechat.open.style=black
wechat.open.href=

# only supported postgresql
datasource.type=com.alibaba.druid.pool.DruidDataSource
datasource.driverClassName=org.postgresql.Driver
datasource.url=jdbc:postgresql://db_host:5432/hiauth?stringtype=unspecified
datasource.username=test
datasource.password=123456

# redis
redis.host=redis_host
redis.port=6379
redis.database=0
redis.username=test
redis.password=123456
```
> 配置参考:[hiauth.properties](https://github.com/bestaone/HiAuth/blob/master/other/hiauth.properties)

### 下载镜像、启动服务 {#download-image}
```shell
# 需要能够访问dockerhub中央仓库,可能需要梯子
$ docker run -d \
  --restart=always \
  -p 9080:80 -p 8080:8080 \
  -v /opt/install/hiauth/conf:/hiauth/conf \
  -v /opt/install/hiauth/logs:/hiauth/logs \
  --name hiauth bestaone/hiauth:3.0.0
  
# 如果无法访问dockerhub中央仓库,可以从阿里云仓库下载镜像
$ docker run -d \
  --restart=always \
  -p 9080:80 -p 8080:8080 \
  -v /opt/install/hiauth/conf:/hiauth/conf \
  -v /opt/install/hiauth/logs:/hiauth/logs \
  --name hiauth registry.cn-zhangjiakou.aliyuncs.com/bestaone/hiauth:3.0.0
  
# 查看镜像  
$ docker images
REPOSITORY                                                 TAG           IMAGE ID       CREATED         SIZE
bestaone/hiauth                                            3.0.0         c5e4140bd5aa   3 hours ago     810MB
registry-vpc.cn-zhangjiakou.aliyuncs.com/bestaone/hiauth   3.0.0         c5e4140bd5aa   3 hours ago     810MB

# 查看服务
$ docker ps
CONTAINER ID   IMAGE                   COMMAND                  CREATED        STATUS       PORTS                                                  NAMES
3ea0fdb8a165   bestaone/hiauth:3.0.0   "/hiauth/run.sh"         3 hours ago    Up 3 hours   8080/tcp, 0.0.0.0:9080->80/tcp, :::9080->80/tcp        hiauth

# 查看日志
$ docker logs 3ea0fdb8a165
...
INFO 7 [main] org.springframework.boot.web.embedded.tomcat.TomcatWebServer Tomcat started on port 8080 (http) with context path '/'
INFO 7 [main] cn.hiauth.server.ServerStarter Started ServerStarter in 10.094 seconds (process running for 11.107)
...

# 访问服务
$ curl http://127.0.0.1:9080
{ "code": 50000, "message": "令牌无效或已过期" }
```
- Docker 版 HiAuth 授权地址为:http://127.0.0.1:9080
- Docker 版 HiAuth 管理地址为:http://127.0.0.1:9080/admin

### 使用HiAuth源码Demo验证 {#hiauth-himall}
- 下载源码
```shell
$ git clone https://github.com/bestaone/HiAuth.git
```
- 修改配置`HiAuth/example/himall/src/main/resources/application.yml`
```yaml
...
spring.security.oauth2.client:
  provider:
    hiauth-server:
      # 将 issuer-uri 的值从 http://auth.hiauth.cn 改为 http://127.0.0.1:9080
      issuer-uri: http://auth.hiauth.cn
...
```
- 编译运行
```shell
$ cd HiAuth/example/himall
$ mvn clean install
$ mvn spring-boot:run
```

### 验证
- 浏览器访问: http://127.0.0.1:9000
- 点击`Login`按钮,会被重定向到统一认证系统,输入账号:`corpadmin`,密码:`123456`
- 登录成功后,会看到首页及登录用户信息!

## 视频教程
<iframe src="//player.bilibili.com/player.html?bvid=BV14hZEYmEEq&page=1" allowfullscreen></iframe>

================================================
FILE: docs/zh/guide/frontend.md
================================================
编辑中...

================================================
FILE: docs/zh/guide/hiauth-client.md
================================================
编辑中...

================================================
FILE: docs/zh/guide/issue.md
================================================
编辑中...


================================================
FILE: docs/zh/guide/k8s.md
================================================
编辑中...

================================================
FILE: docs/zh/guide/quick-start.md
================================================
# 快速体验 {#quikc-start}

## 管理后台 {#admin}

在 [Admin端](http://auth.hiauth.cn/admin) 上体验。
- 系统管理员账号:admin\123456,可以看到所有的配置。通过切换租户,可以查看到当前租户的配置。为了防止乱改数据,此账号只有只读权限。
- 企业管理员账号:corpadmin\123456,可以看到租户内所有的配置。为了防止乱改数据,此账号只有只读权限。

## 统一认证系统 {#auth}

体验 [认证端](http://auth.hiauth.cn) 授权应用登录。三方应用集成后,会被重定向到此页面进行登录认证。

## 文档 {#docs}

在 [文档](http://hiauth.cn) 中获取帮助。

================================================
FILE: docs/zh/guide/saas.md
================================================
# SaaS版 {#saas}

SaaS版的集成,需要用户在HiAuth上开通账号、添加应,并进行相关的设置后,使用你获取的 `client-id` 和 `client-secret` 进行集成。这里为了快速验证,我们使用系统中提供的demo账号来进行集成。等完成验证后,用户可以替换成自己的账号即可。

- HiAuth 授权地址为:http://auth.hiauth.cn
- HiAuth 管理地址为:http://auth.hiauth.cn/admin

## 以SpringBoot项目为例,我们的集成需要以下几步:
- 创建一个SpringBoot项目
- 添加依赖
- 添加配置
- 添加一个首页

只需以上简单几步就可以完成集成SaaS版。

## 运行HiAuth源码自带demo {#hiauth-demo}
### 环境要求
- Git
- JDK 17+
- Maven 3.8+

### 运行脚本
```shell
# 下载HiAuth源码
$ git clone https://github.com/bestaone/HiAuth.git
# 进入demo
$ cd HiAuth/example/himall
# 编译和安装
$ mvn clean install
# 运行
$ mvn spring-boot:run
```
### 验证
- 浏览器访问: http://127.0.0.1:9000
- 点击`Login`按钮,会被重定向到统一认证系统,输入账号:`corpadmin`,密码:`123456`
- 登录成功后,会看到首页及登录用户信息!

## 手把手集成 {#hand-by-hand}
### 环境要求
- JDK 17+
- Maven 3.8+

### 创建一个空的SpringBoot项目

使用 [Spring Initializr](https://start.spring.io/) 创建一个空的SpringBoot项目。pom.xml 文件如下:

```xml [pom.xml]
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
	https://maven.apache.org/xsd/maven-4.0.0.xsd">
    
	<modelVersion>4.0.0</modelVersion>
    
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.4.5</version>
		<relativePath/>
	</parent>
    
	<groupId>cn.hiauth</groupId>
	<artifactId>demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>demo</name>
	<description>Demo project for Spring Boot</description>
    
	<properties>
		<java.version>17</java.version>
	</properties>
    
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>
```

### 添加依赖
```xml [pom.xml]
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
```

### 添加配置
```yml [application.yml]
server.port: 9000
spring.security.oauth2.client:
  provider:
    #认证服务器信息
    hiauth-server:
      # 如果你私有化部署了 HiAuth服务,请将此地址替换为私有部署的认证服务器地址
      issuer-uri: http://auth.hiauth.cn
      authorizationUri: http://auth.hiauth.cn/oauth2/authorize
      #令牌获取地址
      tokenUri: http://auth.hiauth.cn/oauth2/token
      userInfoUri: http://auth.hiauth.cn/userinfo
      jwkSetUri: http://auth.hiauth.cn/oauth2/jwks
      #userNameAttribute: name
  registration:
    hiauth-code:
      #认证提供者,标识由哪个认证服务器进行认证,和上面的hiauth-server进行关联
      provider: hiauth-server
      #客户端名称
      client-name: himall
      #客户端id,从认证平台申请的客户端id
      client-id: himall
      #客户端秘钥
      client-secret: secret
      #客户端认证方式 client_secret_basic\client_secret_post
      client-authentication-method: client_secret_basic
      #使用授权码模式获取令牌(token)
      authorization-grant-type: authorization_code
      # 认证完成后回调的地址,需要在数据库表oauth2_registered_client中登记这个地址,
      # 否则会拒绝回调
      redirect-uri: http://127.0.0.1:9000/login/oauth2/code/hiauth-code
      scope:
        - profile
        - openid
```
> 注意:添加完成 `application.yml` 文件后,将 `application.properties` 文件删除掉

### 添加一个Controller
```java [IndexController.java]
package cn.hiauth.demo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.annotation.RegisteredOAuth2AuthorizedClient;
import org.springframework.ui.Model;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.Map;

@RestController
public class IndexController {

    private final RestTemplate restTemplate = new RestTemplate();

    @Value("${spring.security.oauth2.client.provider.hiauth-server.userInfoUri}")
    private String userInfoUri;

    @GetMapping("/")
    public Map<?, ?> index(Model model, @RegisteredOAuth2AuthorizedClient OAuth2AuthorizedClient oAuth2AuthorizedClient) {
        // 认证完后会获取到 accessToken
        String accessToken = oAuth2AuthorizedClient.getAccessToken().getTokenValue();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        // 设置请求头,将 accessToken 放入请求头中
        headers.add("Authorization", "Bearer " + accessToken);
        MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
        HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(map, headers);
        // 请求认证服务器获取用户信息
        return restTemplate.postForObject(this.userInfoUri, entity, Map.class);
    }

}
```

### 验证

- 启动项目,访问: http://127.0.0.1:9000,系统检测到未登录,会被重定向到统一认证系统;
- 输入账号:`corpadmin`,密码:`123456`,登录成功后,会跳转回应用;
- 这个demo中。首页直接输出了登录用户信息,以`json`格式;
```json
{
  "sub": "corpadmin",
  "empId": 1,
  "avatarUrl": "/unpapi/image/2c924149ddfe4bd181959ee9bede10c0.jpeg",
  "appId": 91,
  "name": "企业管理员",
  "phoneNum": "13400000001",
  "userId": 11,
  "authorities": [],
  "cid": 1,
  "username": "corpadmin"
}
```

## 视频教程
<iframe src="//player.bilibili.com/player.html?bvid=BV1KhZEYmEf1&page=1" scrolling="no" allowfullscreen></iframe>



================================================
FILE: docs/zh/guide/sourcecode.md
================================================
# 源码版 {#sourcecode}
源码版的集成过程和Docker版类似,只不过将Docker版本的HiAuth改为源码编译启动。

## 环境要求 {#env-demand}
- Git
- JDK 17+
- Maven 3.8+
- Nodejs v20.15+
- pnpm 10.10+
- PostgreSQL16+
- Redis

## 安装及集成步骤
- 检查服务器环境
- 下载源码
- 初始化HiAuth数据库,执行SQL脚本
- 配置HiAuth的启动配置文件
- 编译源码、启动服务
- 使用HiAuth源码Demo验证

### 检查服务器环境 {#check-env}
```shell
# 检查git版本
$ git --version
git version 1.8.3.1

# 检查JDK版本
$ java -version
openjdk version "17.0.5" 2022-10-18

# 检查maven版本
$ mvn -v
Apache Maven 3.8.6 (36645f6c9b5079805ea5009217e36f2cffd34256)

# 检查node版本
$ node -v
v20.15.0

# 检查pnpm版本
$ pnpm -v
9.14.2
```

### 下载源码 {#download-source}
```shell
$ git clone https://github.com/bestaone/HiAuth.git
```

### 初始化HiAuth数据库,执行SQL脚本 {#init-db}
- 安装`PostgreSQL16+`;
- 创建数据库`hiauth`;
- 执行初始化脚本 `HiAuth/other/hiauth.sql` ;

### 配置HiAuth的启动配置文件 {#config-file}
- 修改配置文件 `HiAuth/cicd/hiauth.properties`,改成你自己的配置;
```properties [hiauth.properties]
# only supported postgresql
datasource.type=com.alibaba.druid.pool.DruidDataSource
datasource.driverClassName=org.postgresql.Driver
datasource.url=jdbc:postgresql://db_host:5432/hiauth
datasource.username=test
datasource.password=123456

redis.host=redis_host
redis.port=6379
redis.database=0
redis.username=test
redis.password=123456
```
- 应用配置文件,修改`HiAuth/hiauth-server/src/main/resources/application.yml`;
```yaml
...
# 将 /hiauth/conf/hiauth.properties 替换为你上面配置的文件路径
spring.config.import: ${CONFIG_FILE:optional:/hiauth/conf/hiauth.properties}
...
```

### 编译源码、启动服务 {#compile-start}
```shell
# 编译、启动服务端
$ cd HiAuth/hiauth-server
$ mvn clean install
$ mvn spring-boot:run

# 编译、启动前端
$ cd HiAuth/hiauth-front
$ pnpm install
$ pnpm dev:auth

# 访问服务
$ curl http://127.0.0.1:8080
{ "code": 50000, "message": "令牌无效或已过期" }
```
- 检查后端服务:http://127.0.0.1:8080
- 检查前端服务:http://127.0.0.1:5666/admin (端口可能会变化,请自行查看控制台)

### 使用HiAuth源码Demo验证 {#hiauth-himall}
- 修改配置`HiAuth/example/himall/src/main/resources/application.yml`
```yaml
...
spring.security.oauth2.client:
  provider:
    hiauth-server:
      # 将 issuer-uri 的值从 http://auth.hiauth.cn 改为 http://127.0.0.1:8080
      issuer-uri: http://auth.hiauth.cn
...
```
- 编译运行
```shell
$ cd HiAuth/example/himall
$ mvn clean install
$ mvn spring-boot:run
```

### 验证
- 浏览器访问: http://127.0.0.1:9000
- 点击`Login`按钮,会被重定向到统一认证系统,输入账号:`corpadmin`,密码:`123456`
- 登录成功后,会看到首页及登录用户信息!

## 视频教程
<iframe src="//player.bilibili.com/player.html?bvid=BV1KhZEYmERF&page=1" allowfullscreen></iframe>

================================================
FILE: docs/zh/guide/test.md
================================================
编辑中...

================================================
FILE: docs/zh/guide/what-is-hiauth.md
================================================
# HiAuth是什么? {#what-is-hiauth}

HiAuth是一个基于OAuth2.0协议的认证授权系统,通过集成HiAuth系统可以快速的开启应用的认证和授权功能。HiAuth支持SaaS模式、Docker私有化部署模式、源码编译安装模式。而且完全免费,完全开源。

<div class="tip custom-block" style="padding-top: 8px">

想尝试一下?跳到 [快速开始](./quick-start)。

</div>

## 功能 {#function}

### **1. 登录认证**
基于`OAuth2.0`授权协议,允许第三方应用在用户授权下访问其资源,而无需共享用户凭证。
- **核心流程**:
    - **授权码模式**:适用于Web应用,通过授权码交换访问令牌(最安全)。
    - **隐式模式**:适用于单页应用(SPA),直接返回访问令牌(无刷新令牌)。
    - **密码模式**:用户直接提供账号密码给客户端(仅信任场景使用)。
    - **客户端凭证模式**:应用直接以自身身份获取令牌(用于服务间通信)。
- **令牌管理**:
    - 访问令牌(Access Token)用于资源访问,有效期较短。
    - 刷新令牌(Refresh Token)用于获取新访问令牌,需安全存储。
- **安全性**:
    - 强制HTTPS传输,防止令牌泄露。
    - 令牌绑定(Token Binding)防止中间人攻击。

### **2. 访问授权**
访问授权(`Authorization`)决定用户/应用能否执行特定操作或访问资源。基于`RBAC`(基于角色的访问控制),通过角色分配权限(如管理员、普通用户)。

### **3. 应用管理**
管理第三方或内部应用的接入与生命周期。
- **核心功能**:
    - **应用注册**:分配唯一`ClientID`/`ClientSecret`,定义权限范围`Scopes`。
    - **密钥轮换**:定期更新`ClientSecret`,防止泄露风险。
    - **权限控制**:限制应用可访问的API或数据范围。
- **安全审计**:
    - 记录应用行为日志(如API调用频率)。
    - 审核应用权限申请,确保最小权限原则。

### **4. 组织管理**
管理企业或团队的层级结构与成员关系。
- **功能**:
    - **多层级架构**:支持部门、团队、项目组等嵌套结构。
    - **多租户支持**:隔离不同组织的数据与权限(如SaaS场景)。
    - **管理员分配**:设置组织管理员,管理成员与权限。

### **5. 权限管理**
定义和管理用户或角色可执行的操作。
- **核心机制**:
    - **权限粒度**:支持API级、功能级或数据字段级控制。
    - **权限组**:将权限打包为模板(如“财务审批组”)。
    - **权限继承与覆盖**:子角色继承父角色权限,可局部调整。
- **审计与合规**:
    - 权限变更日志:记录谁在何时修改了权限。
    - 定期审查权限分配,避免冗余或过度授权。

### **6. 用户管理**
管理用户身份、认证与生命周期。
- **核心功能**:
    - **身份存储**:支持本地数据库。
    - **生命周期管理**:用户注册、禁用、删除及资料更新。
    - **认证增强**:多因素认证(MFA)、单点登录(SSO)。


## 视频教程
<iframe src="//player.bilibili.com/player.html?bvid=BV1KhZEYmEU9&page=1" allowfullscreen></iframe>

================================================
FILE: docs/zh/index.md
================================================
---
layout: home

title: HiAuth
titleTemplate: 基于OAuth2.0协议的认证授权服务

hero:
  name: HiAuth
  text: 基于OAuth2.0协议的认证授权服务
  tagline: 只需简单几步,即可将认证授权功能集成到你的应用中
  actions:
    - theme: brand
      text: 快速开始 ->
      link: /guide/what-is-hiauth
    - theme: alt
      text: 在线预览
      link: http://auth.hiauth.cn/admin
    - theme: alt
      text: GitHub
      link: https://github.com/bestaone/HiAuth
  image:
      src: /hiauth-large.png
      alt: HiAuth

features:
  - icon: 📝
    title: 登录认证
    details: 单点登录、多端登录、单端登录、互斥登录、免登录... 多种登录策略可配置。
  - icon: 🔐
    title: 权限管理
    details: 权限认证、角色管理、权限管理、菜单管理、会话管理、接口鉴权... 多种方案灵活鉴权。
  - icon: 🌐
    title: OAuth2.0协议
    details: 基于OAuth2.0协议的认证服务,支持四种授权模式,方便与不同开发语言环境对接。
  - icon: 🚀
    title: 开箱即用
    details: 提供SaaS版、一键部署Docker版、源码本地部署版,可以基于源码二次开发,免费、开源。
---


================================================
FILE: example/demo/pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.4.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>cn.hiauth</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>17</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-client</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>


================================================
FILE: example/demo/src/main/java/cn/hiauth/demo/DemoApplication.java
================================================
package cn.hiauth.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}


================================================
FILE: example/demo/src/main/java/cn/hiauth/demo/IndexController.java
================================================
package cn.hiauth.demo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.annotation.RegisteredOAuth2AuthorizedClient;
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
import org.springframework.ui.Model;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.Map;

@RestController
public class IndexController {

    private final RestTemplate restTemplate = new RestTemplate();

    @Value("${spring.security.oauth2.client.provider.hiauth-server.userInfoUri}")
    private String userInfoUri;

    @GetMapping("/")
    public Map<?, ?> index(Model model, @RegisteredOAuth2AuthorizedClient OAuth2AuthorizedClient oAuth2AuthorizedClient, @AuthenticationPrincipal OidcUser oidcUser) {
        // 认证完后会获取到 accessToken
        String accessToken = oAuth2AuthorizedClient.getAccessToken().getTokenValue();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        // 设置请求头,将 accessToken 放入请求头中
        headers.add("Authorization", "Bearer " + accessToken);
        MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
        HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(map, headers);
        // 请求认证服务器获取用户信息
        return restTemplate.postForObject(this.userInfoUri, entity, Map.class);
    }

}

================================================
FILE: example/demo/src/main/resources/application.yml
================================================
server.port: 9000

logging.level:
  root: DEBUG

spring.security.oauth2.client:
  provider:
    #认证服务器信息
    hiauth-server:
      # 如果你私有化部署了 HiAuth服务,请将此地址替换为私有部署的认证服务器地址
      issuer-uri: http://auth.hiauth.cn
      authorizationUri: ${spring.security.oauth2.client.provider.hiauth-server.issuer-uri}/oauth2/authorize
      tokenUri: ${spring.security.oauth2.client.provider.hiauth-server.issuer-uri}/oauth2/token
      userInfoUri: ${spring.security.oauth2.client.provider.hiauth-server.issuer-uri}/userinfo
      jwkSetUri: ${spring.security.oauth2.client.provider.hiauth-server.issuer-uri}/oauth2/jwks
      #userNameAttribute: name
  registration:
    hiauth-code:
      #认证提供者,标识由哪个认证服务器进行认证,和上面的hiauth-server进行关联
      provider: hiauth-server
      client-name: himall
      client-id: himall
      client-secret: secret
      #客户端认证方式 client_secret_basic\client_secret_post
      client-authentication-method: client_secret_basic
      #使用授权码模式获取令牌(token)
      authorization-grant-type: authorization_code
      # 认证完成后回调的地址,需要在数据库表oauth2_registered_client中登记这个地址,
      # 否则会拒绝回调
      redirect-uri: http://127.0.0.1:9000/login/oauth2/code/hiauth-code
      scope: openid,profile

================================================
FILE: example/hiauth-client/pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.4.5</version>
        <relativePath/>
    </parent>

    <groupId>cn.hiauth</groupId>
    <artifactId>hiauth-client</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <name>hiauth-client</name>
    <description>集成HiAuth认证系统</description>

    <properties>
        <java.version>17</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>webjars-locator-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>bootstrap</artifactId>
            <version>3.3.7</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId>
            <version>3.6.3</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>cn.hiauth</groupId>
            <artifactId>hiauth-client-spring-boot-starter</artifactId>
            <version>1.0.9</version>
        </dependency>
    </dependencies>

    <build>
        <finalName>hiauth-client</finalName>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <configuration>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>17</source>
                    <target>17</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>


================================================
FILE: example/hiauth-client/src/main/java/cn/hiauth/hiauthclient/HiauthClientStarter.java
================================================
package cn.hiauth.hiauthclient;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@ComponentScan(basePackages = {"cn.hiauth.client", "cn.hiauth.hiauthclient"})
@SpringBootApplication
public class HiauthClientStarter {

    public static void main(String[] args) {
        SpringApplication.run(HiauthClientStarter.class, args);
    }

}


================================================
FILE: example/hiauth-client/src/main/java/cn/hiauth/hiauthclient/config/WebMvcConfig.java
================================================
package cn.hiauth.hiauthclient.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.http.CacheControl;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.concurrent.TimeUnit;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**", "/webjars/**")
                .addResourceLocations("classpath:/static/", "classpath:/META-INF/resources/webjars/")
                .setCacheControl(CacheControl.maxAge(0, TimeUnit.HOURS).cachePrivate());
    }

}


================================================
FILE: example/hiauth-client/src/main/java/cn/hiauth/hiauthclient/controller/ApiController.java
================================================
package cn.hiauth.hiauthclient.controller;

import cn.hiauth.client.Authentication;
import cn.hiauth.client.SessionContextHolder;
import cn.webestar.scms.commons.R;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Slf4j
@Validated
@RestController
@RequestMapping("/api")
public class ApiController {

    @GetMapping("/getAuth")
    public R<Authentication> getAuth(HttpServletRequest request) {
        Authentication auth = SessionContextHolder.getAuthentication();
        return R.success(auth);
    }

}


================================================
FILE: example/hiauth-client/src/main/java/cn/hiauth/hiauthclient/controller/IndexController.java
================================================
package cn.hiauth.hiauthclient.controller;

import cn.hiauth.client.Authentication;
import cn.hiauth.client.Constant;
import cn.hiauth.client.SessionContextHolder;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;

import java.time.LocalDateTime;

@Slf4j
@Controller
public class IndexController {

    @GetMapping({"/", "/index"})
    public String index(HttpServletRequest request, HttpServletResponse response, Model model) {
        // 这个为了简单就直接判断accessToken了,实际情况应该判断 SessionContextHolder.getContext().getAuth()
        String accessToken = request.getParameter(Constant.PARAMETER_TOKEN_KEY);
        if (StringUtils.hasText(accessToken)) {
            request.getSession().setAttribute("isAuth", true);
            model.addAttribute(Constant.PARAMETER_TOKEN_KEY, accessToken);
        } else {
            request.getSession().setAttribute("isAuth", false);
        }
        return "index";
    }

    @GetMapping("/api/profile")
    public String profile(HttpServletRequest request, Model model) {
        Authentication auth = SessionContextHolder.getContext().getAuth();
        model.addAttribute(Constant.PARAMETER_TOKEN_KEY, request.getParameter(Constant.PARAMETER_TOKEN_KEY));
        model.addAttribute("name", auth.getName());
        model.addAttribute("username", auth.getUsername());
        model.addAttribute("tel", auth.getPhoneNum());
        model.addAttribute("lastLoginTime", LocalDateTime.now());
        request.getSession().setAttribute("isAuth", true);
        return "profile";
    }

}

================================================
FILE: example/hiauth-client/src/main/resources/application.yml
================================================
server.port: 9000

logging.level:
  root: INFO
  cn.hiauth: DEBUG

spring.security.oauth2.client:
  provider:
    #认证服务器信息
    hiauth-server:
      # 如果你私有化部署了 HiAuth服务,请将此地址替换为私有部署的认证服务器地址
      issuer-uri: http://auth.hiauth.cn
      authorizationUri: ${spring.security.oauth2.client.provider.hiauth-server.issuer-uri}/oauth2/authorize
      tokenUri: ${spring.security.oauth2.client.provider.hiauth-server.issuer-uri}/oauth2/token
      userInfoUri: ${spring.security.oauth2.client.provider.hiauth-server.issuer-uri}/userinfo
      jwkSetUri: ${spring.security.oauth2.client.provider.hiauth-server.issuer-uri}/oauth2/jwks
      #userNameAttribute: name
  registration:
    hiauth-code:
      #认证提供者,标识由哪个认证服务器进行认证,和上面的hiauth-server进行关联
      provider: hiauth-server
      client-name: himall
      client-id: himall
      client-secret: secret
      #客户端认证方式 client_secret_basic\client_secret_post
      client-authentication-method: client_secret_basic
      #使用授权码模式获取令牌(token)
      authorization-grant-type: authorization_code
      # 认证完成后回调的地址,需要在数据库表oauth2_registered_client中登记这个地址,否则会拒绝回调
      redirect-uri: http://127.0.0.1:9000/oauth2/token/redirect
      scope: openid,profile

app.security.enable: true

hiauth.client:
  cachePrefix: hiauthclient
  checkPermission: false
  authSuccessRedirectUri: http://127.0.0.1:9000
  authUris:
    - /api/**
  ignoreUris:
    - /unpapi/**

spring.data.redis:
  host: 192.168.3.143
  port: 26379
  database: 0
  username:
  password: Vking1357!
  timeout: 10000
  connect-timeout: 10000

================================================
FILE: example/hiauth-client/src/main/resources/logback.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">

    <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
    <property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %level ${PID} [%thread] %logger %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}" />
    <!-- 彩色日志格式 -->
    <property name="LOG_PATTERN_COLORED" value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%level){blue} %clr(${PID}) %clr([%thread]){orange} %clr(%logger){cyan} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}" />
    <property name="LOG_FILE" value="hiauth-client.log"/>

    <!-- 彩色日志依赖的渲染类 -->
    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
    <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
    <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />

    <!-- 控制台输出 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <withJansi>false</withJansi>
        <encoder>
            <pattern>${LOG_PATTERN_COLORED}</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder>
            <pattern>${LOG_PATTERN}</pattern>
            <charset class="java.nio.charset.Charset">UTF-8</charset>
        </encoder>
        <file>${LOG_FILE}</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
            <fileNamePattern>${LOG_FILE}.%i.zip</fileNamePattern>
            <minIndex>1</minIndex>
            <maxIndex>10</maxIndex>
        </rollingPolicy>
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <MaxFileSize>100MB</MaxFileSize>
        </triggeringPolicy>
    </appender>

    <!-- 日志输出级别 -->
    <root level="INFO">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="FILE"/>
    </root>

</configuration>


================================================
FILE: example/hiauth-client/src/main/resources/static/css/index.css
================================================
/* Space out content a bit */
body {
  padding-top: 20px;
  padding-bottom: 20px;
}

/* Everything but the jumbotron gets side spacing for mobile first views */
.header,
.marketing,
.footer {
  padding-right: 15px;
  padding-left: 15px;
}

/* Custom page header */
.header {
  padding-bottom: 20px;
  border-bottom: 1px solid #e5e5e5;
}
/* Make the masthead heading the same height as the navigation */
.header h3 {
  margin-top: 0;
  margin-bottom: 0;
  line-height: 40px;
}

/* Custom page footer */
.footer {
  padding-top: 19px;
  color: #777;
  border-top: 1px solid #e5e5e5;
}

/* Customize container */
@media (min-width: 768px) {
  .container {
    max-width: 730px;
  }
}
.container-narrow > hr {
  margin: 30px 0;
}

/* Main marketing message and sign up button */
.jumbotron {
  text-align: center;
  border-bottom: 1px solid #e5e5e5;
}
.jumbotron .btn {
  padding: 14px 24px;
  font-size: 21px;
}

/* Supporting marketing content */
.marketing {
  margin: 40px 0;
}
.marketing p + h4 {
  margin-top: 28px;
}

/* Responsive: Portrait tablets and up */
@media screen and (min-width: 768px) {
  /* Remove the padding we set earlier */
  .header,
  .marketing,
  .footer {
    padding-right: 0;
    padding-left: 0;
  }
  /* Space out the masthead */
  .header {
    margin-bottom: 30px;
  }
  /* Remove the bottom border on the jumbotron for visual effect */
  .jumbotron {
    border-bottom: 0;
  }
}


================================================
FILE: example/hiauth-client/src/main/resources/templates/demo.html
================================================
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org" xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
    <head>
        <title>Spring Security OAuth 2.0 Sample</title>
        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <link th:rel="stylesheet" th:href="@{/webjars/bootstrap/3.3.7/css/bootstrap.min.css} ">
    </head>
    <body>
        <div th:fragment="header">
            <nav class="navbar navbar-default">
                <div class="container">
                    <div class="container-fluid">
                        <div class="navbar-collapse collapse" id="navbar">
                        </div>
                    </div>
                </div>
            </nav>
        </div>
        <div class="container">
            <div th:if="${error}" class="alert alert-danger alert-dismissible" role="alert">
                <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                <h4 th:text="${error}" class="text-center"></h4>
            </div>
            <div class="panel panel-default">
                <div class="panel-heading">
                    <h3 class="panel-title">Authorize the client using <span style="font-family:monospace">grant_type</span>:</h3>
                </div>
                <ul class="list-group">
                    <li class="list-group-item">
                        <a href="/authorize?grant_type=authorization_code" th:href="@{/authorize?grant_type=authorization_code}"><span style="font-size:medium">Authorization Code</span>&nbsp;&nbsp;<small class="text-muted">(Login to Spring Authorization Server using: user1/password)</small></a>
                    </li>
                    <li class="list-group-item">
                        <a href="/authorize?grant_type=client_credentials" th:href="@{/authorize?grant_type=client_credentials}"><span style="font-size:medium">Client Credentials</span></a>
                    </li>
                </ul>
                <div th:if="${messages}" class="panel-footer">
                    <h4>Messages:</h4>
                    <table class="table table-condensed">
                        <tbody>
                            <tr class="row" th:each="message : ${messages}">
                                <td th:text="${message}">message</td>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
        <script src="/webjars/jquery/jquery.min.js" th:src="@{/webjars/jquery/3.6.3/jquery.min.js}"></script>
        <script th:src="@{/webjars/bootstrap/3.3.7/js/bootstrap.min.js}"></script>
    </body>
</html>


================================================
FILE: example/hiauth-client/src/main/resources/templates/index.html
================================================
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <title>HiMall</title>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">
    <link rel="icon" th:href="@{/static/favicon.ico}">
    <link th:rel="stylesheet" th:href="@{/webjars/bootstrap/3.3.7/css/bootstrap.min.css} ">
    <link th:href="@{/static/css/index.css}" rel="stylesheet">
</head>
<body>

<div class="container">
    <div class="header clearfix">
        <nav>
            <ul class="nav nav-pills pull-right">
                <li role="presentation" class="active"><a th:href="'/?accessToken=' + ${accessToken}">Home</a></li>
                <li role="presentation" th:if="${session.isAuth!=null ? session.isAuth : false}"><a th:href="'/api/profile?accessToken=' + ${accessToken}">Profile</a></li>
                <li role="presentation" th:if="${session.isAuth!=null ? !session.isAuth : true}"><a th:href="'/oauth2/login?accessToken=' + ${accessToken}">Login</a></li>
                <li role="presentation" th:if="${session.isAuth!=null ? session.isAuth : false}"><a th:href="'/oauth2/logout?accessToken=' + ${accessToken}">Logout</a></li>
            </ul>
        </nav>
        <h3 class="text-muted">HIMALL</h3>
    </div>

    <div class="jumbotron">
        <h1>HiMall Example</h1>
        <p class="lead">This example is a quick exercise to illustrate how Integrate HiAuth by Oauth2, an integrated instance of microservices is also included here, so you can find some best practices.</p>
        <p><a class="btn btn-lg btn-success" href="https://github.com/bestaone/HiAuth" role="button">View HiMall docs</a></p>
    </div>

    <div class="row marketing">
        <div class="col-lg-6"></div>
        <div class="col-lg-6"></div>
    </div>

    <footer class="footer">
        <p>&copy; HiMall system for hiauth.com, by 码道功臣@webestar.cn</p>
    </footer>

</div>

<script th:src="@{/webjars/bootstrap/3.3.7/js/bootstrap.min.js}"></script>

</body>
</html>


================================================
FILE: example/hiauth-client/src/main/resources/templates/profile.html
================================================
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <title>HiMall</title>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">
    <link rel="icon" th:href="@{/static/favicon.ico}">
    <link th:rel="stylesheet" th:href="@{/webjars/bootstrap/3.3.7/css/bootstrap.min.css} ">
    <link th:href="@{/static/css/index.css}" rel="stylesheet">
</head>
<body>

<div class="container">
    <div class="header clearfix">
        <nav>
            <ul class="nav nav-pills pull-right">
                <li role="presentation"><a th:href="'/?accessToken=' + ${accessToken}">Home</a></li>
                <li role="presentation" th:if="${session.isAuth!=null ? session.isAuth : false}" class="active"><a th:href="'/api/profile?accessToken=' + ${accessToken}">Profile</a></li>
                <li role="presentation" th:if="${session.isAuth!=null ? !session.isAuth : true}"><a th:href="'/oauth2/login?accessToken=' + ${accessToken}">Login</a></li>
                <li role="presentation" th:if="${session.isAuth!=null ? session.isAuth : false}"><a th:href="'/oauth2/logout?accessToken=' + ${accessToken}">Logout</a></li>
            </ul>
        </nav>
        <h3 class="text-muted">HIMALL</h3>
    </div>

    <div style="margin-top: 30px;"><span class="glyphicon glyphicon-user" aria-hidden="true"></span> 用户信息</div>
    <div class="row">
        <div class="col-md-2 title">用户姓名:</div><div class="col-md-4 text" th:text="${name}"></div>
        <div class="col-md-2 title">用户账号:</div><div class="col-md-4 text" th:text="${username}"></div>
        <div class="col-md-2 title">手机号码:</div><div class="col-md-4 text" th:text="${tel}"></div>
        <div class="col-md-2 title">最近登录:</div><div class="col-md-4 text" th:text="${lastLoginTime}"></div>
    </div>

    <div style="margin-top: 30px;"><span class="glyphicon glyphicon-list-alt" aria-hidden="true"></span> 我的订单</div>
    <div class="row">
        <div class="col-md-2 title">订单编号:</div><div class="col-md-4 text" th:text="${orderNo}"></div>
        <div class="col-md-2 title">订单标题:</div><div class="col-md-4 text" th:text="${orderTitle}"></div>
        <div class="col-md-2 title">创建时间:</div><div class="col-md-4 text" th:text="${orderCreateTime}"></div>
        <div class="col-md-2 title">订单总额:</div><div class="col-md-4 text" th:text="${orderTotalAmount}"></div>
    </div>

    <div class="row" style="margin-top: 30px; padding: 0px 15px;">
        <div class="panel panel-default">
            <div class="panel-heading">商品列表</div>
            <table class="table">
                <thead>
                    <tr>
                        <th>#</th>
                        <th>商品名称</th>
                        <th>单价(元)</th>
                        <th>库存(个)</th>
                        <th>上架时间</th>
                    </tr>
                </thead>
                <tbody>
                    <tr th:each="goods,stat : ${goodsList}">
                        <th scope="row" th:text="${stat.index + 1}"></th>
                        <td th:text="${goods.title}"></td>
                        <td th:text="${goods.price}"></td>
                        <td th:text="${goods.amount}"></td>
                        <td th:text="${goods.createTime}"></td>
                    </tr>
                </tbody>
            </table>

        </div>
    </div>

    <footer class="footer">
        <p>&copy; HiMall system for hiauth.com, by 码道功臣@webestar.cn.</p>
    </footer>

</div>

<script th:src="@{/webjars/bootstrap/3.3.7/js/bootstrap.min.js}"></script>

</body>
</html>


================================================
FILE: example/hiauth-client-exp/pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.4.5</version>
        <relativePath/>
    </parent>

    <groupId>cn.hiauth</groupId>
    <artifactId>hiauth-client-exp</artifactId>
    <version>3.0.0-SNAPSHOT</version>
    <name>hiauth-server</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>17</java.version>
    </properties>

    <dependencies>
        <!-- Spring Boot Starters -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-client</artifactId>
        </dependency>
    </dependencies>

    <build>
        <finalName>hiauth-client-exp</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.graalvm.buildtools</groupId>
                <artifactId>native-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>


================================================
FILE: example/hiauth-client-exp/src/main/java/cn/hiauth/client/ClientStarter.java
================================================
package cn.hiauth.client;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ClientStarter {

    public static void main(String[] args) {
        SpringApplication.run(ClientStarter.class, args);
    }

}


================================================
FILE: example/hiauth-client-exp/src/main/java/cn/hiauth/client/config/BeanConfig.java
================================================
package cn.hiauth.client.config;

import org.springframework.context.annotation.Configuration;

@Configuration
public class BeanConfig {

}


================================================
FILE: example/hiauth-client-exp/src/main/java/cn/hiauth/client/config/SecurityConfig.java
================================================
package cn.hiauth.client.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

}

================================================
FILE: example/hiauth-client-exp/src/main/java/cn/hiauth/client/config/WebMvcConfig.java
================================================
package cn.hiauth.client.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.CacheControl;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.concurrent.TimeUnit;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Value("${app.cacheControl.maxAge:0}")
    private Integer maxAge;

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**", "/webjars/**")
                .addResourceLocations("classpath:/static/", "classpath:/META-INF/resources/webjars/")
                .setCacheControl(CacheControl.maxAge(maxAge, TimeUnit.HOURS).cachePrivate());
    }

}

================================================
FILE: example/hiauth-client-exp/src/main/java/cn/hiauth/client/controller/ClientController.java
================================================
package cn.hiauth.client.controller;

import org.springframework.stereotype.Controller;

@Controller
public class ClientController {

}


================================================
FILE: example/hiauth-client-exp/src/main/resources/application.yml
================================================
server.port: 9000

spring.security.oauth2.client:
  provider:
    hiauth-code:
      issuer-uri: http://localhost:8080
      authorizationUri: ${spring.security.oauth2.client.provider.hiauth-server.issuer-uri}/oauth2/authorize
      tokenUri: ${spring.security.oauth2.client.provider.hiauth-server.issuer-uri}/oauth2/token
      userInfoUri: ${spring.security.oauth2.client.provider.hiauth-server.issuer-uri}/userinfo
      jwkSetUri: ${spring.security.oauth2.client.provider.hiauth-server.issuer-uri}/oauth2/jwks
      user-name-attribute: sub
  registration:
    hiauth-code:
      client-name: HiAuth Authorization Server
      client-id: himall
      client-secret: secret
      authorization-grant-type: authorization_code
      redirect-uri: http://127.0.0.1:9000/login/oauth2/code/hiauth-code
      scope: openid,profile

================================================
FILE: example/hiauth-client-exp/src/main/resources/logback.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">

    <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
    <property name="LOG_PATTERN"
              value="%d{yyyy-MM-dd HH:mm:ss.SSS} %level ${PID} [%thread] %logger %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
    <!-- 彩色日志格式 -->
    <property name="LOG_PATTERN_COLORED"
              value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%level){blue} %clr(${PID}) %clr([%thread]){orange} %clr(%logger){cyan} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
    <property name="LOG_FILE" value="./hiauth/logs/client.log"/>

    <!-- 彩色日志依赖的渲染类 -->
    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
    <conversionRule conversionWord="wex"
                    converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
    <conversionRule conversionWord="wEx"
                    converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>

    <!-- 控制台输出 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <withJansi>false</withJansi>
        <encoder>
            <pattern>${LOG_PATTERN_COLORED}</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder>
            <pattern>${LOG_PATTERN}</pattern>
            <charset class="java.nio.charset.Charset">UTF-8</charset>
        </encoder>
        <file>${LOG_FILE}</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
            <fileNamePattern>${LOG_FILE}.%i.zip</fileNamePattern>
            <minIndex>1</minIndex>
            <maxIndex>10</maxIndex>
        </rollingPolicy>
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <MaxFileSize>100MB</MaxFileSize>
        </triggeringPolicy>
    </appender>

    <!-- 日志输出级别 -->
    <root level="INFO">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="FILE"/>
    </root>

</configuration>


================================================
FILE: example/hiauth-client-exp/src/main/resources/templates/index.html
================================================
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>OAuth2 Client Demo</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
index
</body>
</html>

================================================
FILE: example/hiauth-server-exp/pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.4.5</version>
        <relativePath/>
    </parent>

    <groupId>cn.hiauth</groupId>
    <artifactId>hiauth-server-exp</artifactId>
    <version>3.0.0-SNAPSHOT</version>
    <name>hiauth-server</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>17</java.version>
    </properties>

    <dependencies>
        <!-- 开发支持:热启动等 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <!-- web服务必选 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- authorization server -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-authorization-server</artifactId>
        </dependency>
        <!-- Spring Boot验证依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <!-- thymeleaf -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <!-- redis session 如果客户端session出现问题可以尝试打开
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-data-redis</artifactId>
        </dependency>
        -->
        <!-- hutool -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.38</version>
        </dependency>
        <!-- lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- scms -->
        <dependency>
            <groupId>cn.webestar.scms</groupId>
            <artifactId>commons</artifactId>
            <version>1.2.0</version>
        </dependency>
        <!-- 数据库 -->
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.24</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-oauth2-client</artifactId>
        </dependency>
    </dependencies>

    <build>
        <finalName>hiauth-server</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.graalvm.buildtools</groupId>
                <artifactId>native-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>


================================================
FILE: example/hiauth-server-exp/src/main/java/cn/hiauth/server/ServerStarter.java
================================================
package cn.hiauth.server;

import cn.webestar.scms.commons.Constant;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@ComponentScan(basePackages = {"cn.hiauth.server", Constant.SCMS_BASIC_PKG})
@SpringBootApplication
public class ServerStarter {

    public static void main(String[] args) {
        SpringApplication.run(ServerStarter.class, args);
    }

}


================================================
FILE: example/hiauth-server-exp/src/main/java/cn/hiauth/server/config/AuthServerConfig.java
================================================
package cn.hiauth.server.config;

import cn.hiauth.server.federation.FederatedIdentityIdTokenCustomizer;
import cn.hiauth.server.mapper.SimpleJdbcRegisteredClientRepository;
import cn.hiauth.server.utils.jose.Jwks;
import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.jwk.RSAKey;
import com.nimbusds.jose.jwk.source.JWKSource;
import com.nimbusds.jose.proc.SecurityContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.MediaType;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationConsentService;
import org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationService;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration;
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer;
import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings;
import org.springframework.security.oauth2.server.authorization.token.JwtEncodingContext;
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenCustomizer;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
import org.springframework.security.web.util.matcher.MediaTypeRequestMatcher;

@Configuration(proxyBeanMethods = false)
public class AuthServerConfig {

    /**
     * Spring Authorization Server 相关配置
     * 主要配置OAuth 2.1和OpenID Connect 1.0
     */
    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
        OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = OAuth2AuthorizationServerConfigurer.authorizationServer();
        http
                .securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
                .with(authorizationServerConfigurer, (authorizationServer) ->
                        authorizationServer
                                .authorizationEndpoint(authorizationEndpoint -> authorizationEndpoint.consentPage("/oauth2/consent"))
                                .oidc(Customizer.withDefaults())
                )
                .authorizeHttpRequests((authorize) ->
                        authorize.anyRequest().authenticated()
                )
                .exceptionHandling((exceptions) -> exceptions
                        .defaultAuthenticationEntryPointFor(
                                new LoginUrlAuthenticationEntryPoint("/login"),
                                new MediaTypeRequestMatcher(MediaType.TEXT_HTML)
                        )
                )
                .oauth2ResourceServer((resourceServer) -> resourceServer.jwt(Customizer.withDefaults()));
        return http.build();
    }

    /**
     * 客户端信息
     * 对应表:oauth2_registered_client
     */
    @Bean
    public SimpleJdbcRegisteredClientRepository registeredClientRepository(JdbcTemplate jdbcTemplate) {
        return new SimpleJdbcRegisteredClientRepository(jdbcTemplate);
    }

    @Bean
    public JdbcOAuth2AuthorizationService authorizationService(JdbcTemplate jdbcTemplate, RegisteredClientRepository registeredClientRepository) {
        return new JdbcOAuth2AuthorizationService(jdbcTemplate, registeredClientRepository);
    }

    @Bean
    public JdbcOAuth2AuthorizationConsentService authorizationConsentService(JdbcTemplate jdbcTemplate, RegisteredClientRepository registeredClientRepository) {
        return new JdbcOAuth2AuthorizationConsentService(jdbcTemplate, registeredClientRepository);
    }

    @Bean
    public OAuth2TokenCustomizer<JwtEncodingContext> idTokenCustomizer() {
        return new FederatedIdentityIdTokenCustomizer();
    }

    @Bean
    public JWKSource<SecurityContext> jwkSource() {
        RSAKey rsaKey = Jwks.generateRsa();
        JWKSet jwkSet = new JWKSet(rsaKey);
        return (jwkSelector, securityContext) -> jwkSelector.select(jwkSet);
    }

    @Bean
    public JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
        return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
    }

    @Bean
    public AuthorizationServerSettings authorizationServerSettings() {
        return AuthorizationServerSettings.builder().build();
    }

}


================================================
FILE: example/hiauth-server-exp/src/main/java/cn/hiauth/server/config/BeanConfig.java
================================================
package cn.hiauth.server.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;

@Slf4j
@Configuration
public class BeanConfig {

}


================================================
FILE: example/hiauth-server-exp/src/main/java/cn/hiauth/server/config/SecurityConfig.java
================================================
package cn.hiauth.server.config;

import cn.hiauth.server.federation.FederatedIdentityAuthenticationSuccessHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.session.HttpSessionEventPublisher;

@EnableWebSecurity
@Configuration(proxyBeanMethods = true)
@EnableMethodSecurity(jsr250Enabled = true, securedEnabled = true)
public class SecurityConfig {

    @Bean
    public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
        http
                .authorizeHttpRequests((authorize) -> authorize
                        .anyRequest().authenticated()
                )
                .cors(Customizer.withDefaults())
                .csrf(AbstractHttpConfigurer::disable)
                .formLogin(Customizer.withDefaults());
        return http.build();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        UserDetails userDetails = User.withDefaultPasswordEncoder()
                .username("user")
                .password("123456")
                .roles("USER")
                .build();
        return new InMemoryUserDetailsManager(userDetails);
    }

    private AuthenticationSuccessHandler authenticationSuccessHandler() {
        return new FederatedIdentityAuthenticationSuccessHandler();
    }

    @Bean
    public SessionRegistry sessionRegistry() {
        return new SessionRegistryImpl();
    }

    @Bean
    public HttpSessionEventPublisher httpSessionEventPublisher() {
        return new HttpSessionEventPublisher();
    }

}


================================================
FILE: example/hiauth-server-exp/src/main/java/cn/hiauth/server/config/WebMvcConfig.java
================================================
package cn.hiauth.server.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.CacheControl;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.concurrent.TimeUnit;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Value("${app.cacheControl.maxAge:0}")
    private Integer maxAge;

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**", "/webjars/**")
                .addResourceLocations("classpath:/static/", "classpath:/META-INF/resources/webjars/")
                .setCacheControl(CacheControl.maxAge(maxAge, TimeUnit.HOURS).cachePrivate());
    }

}

================================================
FILE: example/hiauth-server-exp/src/main/java/cn/hiauth/server/controller/IndexController.java
================================================
package cn.hiauth.server.controller;

import org.springframework.stereotype.Controller;

@Controller
public class IndexController {

}


================================================
FILE: example/hiauth-server-exp/src/main/java/cn/hiauth/server/controller/LoginController.java
================================================
package cn.hiauth.server.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;

@Slf4j
@Controller
public class LoginController {

}


================================================
FILE: example/hiauth-server-exp/src/main/java/cn/hiauth/server/federation/FederatedIdentityAuthenticationSuccessHandler.java
================================================
/*
 * Copyright 2020-2025 the original author or authors.
 *
 * Licensed 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
 *
 *      https://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 cn.hiauth.server.federation;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;

import java.io.IOException;
import java.util.function.Consumer;

/**
 * An {@link AuthenticationSuccessHandler} for capturing the {@link OidcUser} or
 * {@link OAuth2User} for Federated Account Linking or JIT Account Provisioning.
 *
 * @author Steve Riesenberg
 * @since 1.1
 */
public final class FederatedIdentityAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    private final AuthenticationSuccessHandler delegate = new SavedRequestAwareAuthenticationSuccessHandler();

    private Consumer<OAuth2User> oauth2UserHandler = (user) -> {
    };

    private Consumer<OidcUser> oidcUserHandler = (user) -> this.oauth2UserHandler.accept(user);

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        if (authentication instanceof OAuth2AuthenticationToken) {
            if (authentication.getPrincipal() instanceof OidcUser oidcUser) {
                this.oidcUserHandler.accept(oidcUser);
            } else if (authentication.getPrincipal() instanceof OAuth2User oauth2User) {
                this.oauth2UserHandler.accept(oauth2User);
            }
        }

        this.delegate.onAuthenticationSuccess(request, response, authentication);
    }

    public void setOAuth2UserHandler(Consumer<OAuth2User> oauth2UserHandler) {
        this.oauth2UserHandler = oauth2UserHandler;
    }

    public void setOidcUserHandler(Consumer<OidcUser> oidcUserHandler) {
        this.oidcUserHandler = oidcUserHandler;
    }

}


================================================
FILE: example/hiauth-server-exp/src/main/java/cn/hiauth/server/federation/FederatedIdentityIdTokenCustomizer.java
================================================
/*
 * Copyright 2020-2025 the original author or authors.
 *
 * Licensed 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
 *
 *      https://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 cn.hiauth.server.federation;

import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.core.oidc.IdTokenClaimNames;
import org.springframework.security.oauth2.core.oidc.OidcIdToken;
import org.springframework.security.oauth2.core.oidc.endpoint.OidcParameterNames;
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.security.oauth2.server.authorization.token.JwtEncodingContext;
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenCustomizer;

import java.util.*;

/**
 * An {@link OAuth2TokenCustomizer} to map claims from a federated identity to
 * the {@code id_token} produced by this authorization server.
 *
 * @author Steve Riesenberg
 * @since 1.1
 */
public final class FederatedIdentityIdTokenCustomizer implements OAuth2TokenCustomizer<JwtEncodingContext> {

    private static final Set<String> ID_TOKEN_CLAIMS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
            IdTokenClaimNames.ISS,
            IdTokenClaimNames.SUB,
            IdTokenClaimNames.AUD,
            IdTokenClaimNames.EXP,
            IdTokenClaimNames.IAT,
            IdTokenClaimNames.AUTH_TIME,
            IdTokenClaimNames.NONCE,
            IdTokenClaimNames.ACR,
            IdTokenClaimNames.AMR,
            IdTokenClaimNames.AZP,
            IdTokenClaimNames.AT_HASH,
            IdTokenClaimNames.C_HASH
    )));

    @Override
    public void customize(JwtEncodingContext context) {
        if (OidcParameterNames.ID_TOKEN.equals(context.getTokenType().getValue())) {
            Map<String, Object> thirdPartyClaims = extractClaims(context.getPrincipal());
            context.getClaims().claims(existingClaims -> {
                // Remove conflicting claims set by this authorization server
                existingClaims.keySet().forEach(thirdPartyClaims::remove);

                // Remove standard id_token claims that could cause problems with clients
                ID_TOKEN_CLAIMS.forEach(thirdPartyClaims::remove);

                // Add all other claims directly to id_token
                existingClaims.putAll(thirdPartyClaims);
            });
        }
    }

    private Map<String, Object> extractClaims(Authentication principal) {
        Map<String, Object> claims;
        if (principal.getPrincipal() instanceof OidcUser oidcUser) {
            OidcIdToken idToken = oidcUser.getIdToken();
            claims = idToken.getClaims();
        } else if (principal.getPrincipal() instanceof OAuth2User oauth2User) {
            claims = oauth2User.getAttributes();
        } else {
            claims = Collections.emptyMap();
        }
        return new HashMap<>(claims);
    }

}


================================================
FILE: example/hiauth-server-exp/src/main/java/cn/hiauth/server/mapper/SimpleJdbcRegisteredClientRepository.java
================================================
package cn.hiauth.server.mapper;

import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;

import java.util.List;
import java.util.Set;

public class SimpleJdbcRegisteredClientRepository extends JdbcRegisteredClientRepository {

    private static final String TABLE_NAME = "oauth2_registered_client";

    private static final String COLUMN_NAMES = "id, "
            + "client_id, "
            + "client_id_issued_at, "
            + "client_secret, "
            + "client_secret_expires_at, "
            + "client_name, "
            + "client_authentication_methods, "
            + "authorization_grant_types, "
            + "redirect_uris, "
            + "post_logout_redirect_uris, "
            + "scopes, "
            + "client_settings,"
            + "token_settings";

    private static final String LOAD_REGISTERED_CLIENT_SQL = "SELECT " + COLUMN_NAMES + " FROM " + TABLE_NAME + " WHERE ";

    public SimpleJdbcRegisteredClientRepository(JdbcOperations jdbcOperations) {
        super(jdbcOperations);
    }

    public List<RegisteredClient> findByClientIds(Set<String> clientIds) {
        MapSqlParameterSource parameters = new MapSqlParameterSource();
        parameters.addValue("clientIds", clientIds);
        StringBuilder sb = new StringBuilder();
        sb.append(LOAD_REGISTERED_CLIENT_SQL).append("client_id IN (");
        clientIds.forEach(i -> sb.append("'").append(i).append("',"));
        sb.deleteCharAt(sb.length() - 1);
        sb.append(")");
        List<RegisteredClient> result = this.getJdbcOperations().query(sb.toString(), this.getRegisteredClientRowMapper());
        return !result.isEmpty() ? result : null;
    }

}


================================================
FILE: example/hiauth-server-exp/src/main/java/cn/hiauth/server/utils/jose/Jwks.java
================================================
/*
 * Copyright 2020-2023 the original author or authors.
 *
 * Licensed 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
 *
 *      https://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 cn.hiauth.server.utils.jose;

import com.nimbusds.jose.jwk.Curve;
import com.nimbusds.jose.jwk.ECKey;
import com.nimbusds.jose.jwk.OctetSequenceKey;
import com.nimbusds.jose.jwk.RSAKey;

import javax.crypto.SecretKey;
import java.security.KeyPair;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.UUID;

/**
 * @author Joe Grandja
 * @since 1.1
 */
public final class Jwks {

    private Jwks() {
    }

    public static RSAKey generateRsa() {
        KeyPair keyPair = KeyGeneratorUtils.generateRsaKey();
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
        // @formatter:off
		return new RSAKey.Builder(publicKey)
				.privateKey(privateKey)
				.keyID(UUID.randomUUID().toString())
				.build();
		// @formatter:on
    }

    public static ECKey generateEc() {
        KeyPair keyPair = KeyGeneratorUtils.generateEcKey();
        ECPublicKey publicKey = (ECPublicKey) keyPair.getPublic();
        ECPrivateKey privateKey = (ECPrivateKey) keyPair.getPrivate();
        Curve curve = Curve.forECParameterSpec(publicKey.getParams());
        // @formatter:off
		return new ECKey.Builder(curve, publicKey)
				.privateKey(privateKey)
				.keyID(UUID.randomUUID().toString())
				.build();
		// @formatter:on
    }

    public static OctetSequenceKey generateSecret() {
        SecretKey secretKey = KeyGeneratorUtils.generateSecretKey();
        // @formatter:off
		return new OctetSequenceKey.Builder(secretKey)
				.keyID(UUID.randomUUID().toString())
				.build();
		// @formatter:on
    }

}


================================================
FILE: example/hiauth-server-exp/src/main/java/cn/hiauth/server/utils/jose/KeyGeneratorUtils.java
================================================
/*
 * Copyright 2020-2023 the original author or authors.
 *
 * Licensed 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
 *
 *      https://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 cn.hiauth.server.utils.jose;

import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.spec.ECFieldFp;
import java.security.spec.ECParameterSpec;
import java.security.spec.ECPoint;
import java.security.spec.EllipticCurve;

/**
 * @author Joe Grandja
 * @since 1.1
 */
final class KeyGeneratorUtils {

    private KeyGeneratorUtils() {
    }

    static SecretKey generateSecretKey() {
        SecretKey hmacKey;
        try {
            hmacKey = KeyGenerator.getInstance("HmacSha256").generateKey();
        } catch (Exception ex) {
            throw new IllegalStateException(ex);
        }
        return hmacKey;
    }

    static KeyPair generateRsaKey() {
        KeyPair keyPair;
        try {
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(2048);
            keyPair = keyPairGenerator.generateKeyPair();
        } catch (Exception ex) {
            throw new IllegalStateException(ex);
        }
        return keyPair;
    }

    static KeyPair generateEcKey() {
        EllipticCurve ellipticCurve = new EllipticCurve(
                new ECFieldFp(
                        new BigInteger("115792089210356248762697446949407573530086143415290314195533631308867097853951")),
                new BigInteger("115792089210356248762697446949407573530086143415290314195533631308867097853948"),
                new BigInteger("41058363725152142129326129780047268409114441015993725554835256314039467401291"));
        ECPoint ecPoint = new ECPoint(
                new BigInteger("48439561293906451759052585252797914202762949526041747995844080717082404635286"),
                new BigInteger("36134250956749795798585127919587881956611106672985015071877198253568414405109"));
        ECParameterSpec ecParameterSpec = new ECParameterSpec(
                ellipticCurve,
                ecPoint,
                new BigInteger("115792089210356248762697446949407573529996955224135760342422259061068512044369"),
                1);

        KeyPair keyPair;
        try {
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC");
            keyPairGenerator.initialize(ecParameterSpec);
            keyPair = keyPairGenerator.generateKeyPair();
        } catch (Exception ex) {
            throw new IllegalStateException(ex);
        }
        return keyPair;
    }

}


================================================
FILE: example/hiauth-server-exp/src/main/java/cn/hiauth/server/utils/package-info.java
================================================
package cn.hiauth.server.utils;

================================================
FILE: example/hiauth-server-exp/src/main/resources/application-hiauth.yml
================================================
server.port: 8080

logging.level:
  root: INFO
  cn.hiauth: DEBUG
  com.alibaba.nacos: INFO
  org.springframework.data.redis: INFO
  io.lettuce.core: INFO

spring.datasource:
  type: ${datasource.type}
  driver-class-name: ${datasource.driverClassName}
  url: ${datasource.url}
  username: ${datasource.username}
  password: ${datasource.password}

spring.session.timeout: 600m
spring.session.redis:
  # 支持发布session事件,默认值不支持发布session事件
  repository-type: indexed
  namespace: "hiauth:session"
  # 每次保存或更新 session 时立即将数据同步到 Redis
  flush-mode: on_save
  # 每次请求结束时都保存 session
  save-mode: always
  # 关闭Spring Session的自动配置检查,否则在使用aliyun redis(Tair)时会报错
  # 报错内容为:NOPERM this user has no permissions to run the 'config|get' command
  configure-action: none


================================================
FILE: example/hiauth-server-exp/src/main/resources/application-redis.yml
================================================
# 单节点写法
spring.data.redis:
  host: ${redis.host}
  port: ${redis.port}
  database: ${redis.database}
  username: ${redis.username}
  password: ${redis.password}
  timeout: 10000
  connect-timeout: 10000


================================================
FILE: example/hiauth-server-exp/src/main/resources/application.yml
================================================
app.version: '@project.version@'
app.build.timestamp: '@app.build.timestamp@'
spring.application.name: hiauth-server

# 加载模块化配置
spring.profiles.active: hiauth,redis

# 加载外部配置文件,覆盖内置配置文件
spring.config.import: ${CONFIG_FILE:optional:/hiauth/conf/hiauth.properties}

datasource:
  type: com.alibaba.druid.pool.DruidDataSource
  driverClassName: org.postgresql.Driver
  url: jdbc:mysql://${DB_HOST:127.0.0.1}:3306/hiauth
  username: ${DB_USER:test}
  password: ${DB_pwd:123456}

redis:
  host: ${REDIS_HOST:127.0.0.1}
  username: ${REDIS_USERNAME:}
  password: ${REDIS_PWD:}
  port: 6379
  database: 0


================================================
FILE: example/hiauth-server-exp/src/main/resources/logback.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">

    <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
    <property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %level ${PID} [%thread] %logger %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}" />
    <!-- 彩色日志格式 -->
    <property name="LOG_PATTERN_COLORED" value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%level){blue} %clr(${PID}) %clr([%thread]){orange} %clr(%logger){cyan} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}" />
    <property name="LOG_FILE" value="./hiauth/logs/server.log"/>

    <!-- 彩色日志依赖的渲染类 -->
    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
    <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
    <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />

    <!-- 控制台输出 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <withJansi>false</withJansi>
        <encoder>
            <pattern>${LOG_PATTERN_COLORED}</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder>
            <pattern>${LOG_PATTERN}</pattern>
            <charset class="java.nio.charset.Charset">UTF-8</charset>
        </encoder>
        <file>${LOG_FILE}</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
            <fileNamePattern>${LOG_FILE}.%i.zip</fileNamePattern>
            <minIndex>1</minIndex>
            <maxIndex>10</maxIndex>
        </rollingPolicy>
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <MaxFileSize>100MB</MaxFileSize>
        </triggeringPolicy>
    </appender>

    <!-- 日志输出级别 -->
    <root level="INFO">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="FILE"/>
    </root>

</configuration>


================================================
FILE: example/hiauth-server-exp/src/main/resources/templates/index.html
================================================
<!doctype html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
</head>
<body>
index
<a class="dropdown-item" href="/logout">退出</a>
</body>
</html>


================================================
FILE: example/himall/pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.4.5</version>
        <relativePath/>
    </parent>

    <groupId>cn.hiauth</groupId>
    <artifactId>himall</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <name>himall</name>
    <description>集成HiAuth认证系统</description>

    <properties>
        <java.version>17</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>webjars-locator-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>bootstrap</artifactId>
            <version>3.3.7</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId>
            <version>3.6.3</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-client</artifactId>
        </dependency>
    </dependencies>

    <build>
        <finalName>himall</finalName>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <configuration>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>17</source>
                    <target>17</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>


================================================
FILE: example/himall/src/main/java/cn/hiauth/himall/HiMallStarter.java
================================================
package cn.hiauth.himall;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class HiMallStarter {

    public static void main(String[] args) {
        SpringApplication.run(HiMallStarter.class, args);
    }

}


================================================
FILE: example/himall/src/main/java/cn/hiauth/himall/config/SecurityConfig.java
================================================
package cn.hiauth.himall.config;

import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.web.client.RestTemplate;

import static org.springframework.security.config.Customizer.withDefaults;

@EnableWebSecurity
@Configuration(proxyBeanMethods = true)
public class SecurityConfig {

    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) {
        return builder.build();
    }

    @Bean
    WebSecurityCustomizer webSecurityCustomizer() {
        return web -> web.ignoring().requestMatchers("/static/**", "/webjars/**");
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .authorizeHttpRequests(authorize ->
                        authorize.requestMatchers("/", "/index").permitAll().anyRequest().authenticated()
                )
                .oauth2Login(oauth2Login -> oauth2Login.failureUrl("/login?error"))
                .logout(logout -> logout
                        .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                        .invalidateHttpSession(true)
                        .clearAuthentication(true)
                        .deleteCookies("JSESSIONID")
                )
                .oauth2Client(withDefaults());
        return http.build();
    }

}


================================================
FILE: example/himall/src/main/java/cn/hiauth/himall/config/WebMvcConfig.java
================================================
package cn.hiauth.himall.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.http.CacheControl;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.concurrent.TimeUnit;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**", "/webjars/**")
                .addResourceLocations("classpath:/static/", "classpath:/META-INF/resources/webjars/")
                .setCacheControl(CacheControl.maxAge(0, TimeUnit.HOURS).cachePrivate());
    }

}


================================================
FILE: example/himall/src/main/java/cn/hiauth/himall/controller/AuthController.java
================================================
package cn.hiauth.himall.controller;

import jakarta.servlet.http.HttpServletRequest;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.annotation.RegisteredOAuth2AuthorizedClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class AuthController {

    @ResponseBody
    @GetMapping("/api/client")
    public OAuth2AuthorizedClient client(HttpServletRequest request, @RegisteredOAuth2AuthorizedClient OAuth2AuthorizedClient oAuth2AuthorizedClient) {
        // 通过OAuth2AuthorizedClient对象获取到客户端和令牌相关的信息,然后直接返回给前端页面
        request.getSession().setAttribute("isAuth", true);
        return oAuth2AuthorizedClient;
    }

}


================================================
FILE: example/himall/src/main/java/cn/hiauth/himall/controller/IndexController.java
================================================
package cn.hiauth.himall.controller;

import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.annotation.RegisteredOAuth2AuthorizedClient;
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDateTime;
import java.util.Map;

@Slf4j
@Controller
public class IndexController {

    @Autowired
    private RestTemplate restTemplate;

    @Value("${spring.security.oauth2.client.provider.hiauth-server.issuer-uri}")
    private String issuerUri;

    @Value("${spring.security.oauth2.client.provider.hiauth-server.userInfoUri}")
    private String userInfoUri;

    @GetMapping({"/", "/index"})
    public String index(HttpServletRequest request, HttpServletResponse response) {
        return "index";
    }

    @GetMapping("/user/logout")
    public String logout(HttpServletRequest request, HttpServletResponse response) {
        SecurityContextHolder.clearContext();
        Cookie cookie = new Cookie("JSESSIONID", null);
        cookie.setMaxAge(0);
        cookie.setPath("/");
        response.addCookie(cookie);
        return "redirect:" + issuerUri + "/unpapi/logoutWithRedirect?redirect_uri=http://127.0.0.1:9000";
    }

    @GetMapping("/profile")
    public String profile(HttpServletRequest request, Model model, @RegisteredOAuth2AuthorizedClient OAuth2AuthorizedClient oAuth2AuthorizedClient, @AuthenticationPrincipal OidcUser oidcUser) {
        String accessToken = oAuth2AuthorizedClient.getAccessToken().getTokenValue();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        headers.add("Authorization", "Bearer " + accessToken);
        MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
        HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(map, headers);
        Map<?, ?> res = restTemplate.postForObject(this.userInfoUri, entity, Map.class);
        log.info("res:{}", res);
        model.addAttribute("name", res.get("name"));
        model.addAttribute("username", res.get("username"));
        model.addAttribute("tel", res.get("phoneNum"));
        model.addAttribute("lastLoginTime", LocalDateTime.now());
        request.getSession().setAttribute("isAuth", true);
        return "profile";
    }

}

================================================
FILE: example/himall/src/main/resources/application.yml
================================================
server.port: 9000

logging.level:
  root: DEBUG
  cn.hiauth: DEBUG

spring.security.oauth2.client:
  provider:
    #认证服务器信息
    hiauth-server:
      # 如果你私有化部署了 HiAuth服务,请将此地址替换为私有部署的认证服务器地址
      #issuer-uri: http://localhost:8080
      issuer-uri: http://auth.hiauth.cn
      authorizationUri: ${spring.security.oauth2.client.provider.hiauth-server.issuer-uri}/oauth2/authorize
      #令牌获取地址
      tokenUri: ${spring.security.oauth2.client.provider.hiauth-server.issuer-uri}/oauth2/token
      userInfoUri: ${spring.security.oauth2.client.provider.hiauth-server.issuer-uri}/userinfo
      jwkSetUri: ${spring.security.oauth2.client.provider.hiauth-server.issuer-uri}/oauth2/jwks
      #userNameAttribute: name
  registration:
    hiauth-code:
      #认证提供者,标识由哪个认证服务器进行认证,和上面的hiauth-server进行关联
      provider: hiauth-server
      client-name: himall
      client-id: himall
      client-secret: secret
      #客户端认证方式 client_secret_basic\client_secret_post
      client-authentication-method: client_secret_basic
      #使用授权码模式获取令牌(token)
      authorization-grant-type: authorization_code
      # 认证完成后回调的地址,需要在数据库表oauth2_registered_client中登记这个地址,否则会拒绝回调
      redirect-uri: http://127.0.0.1:9000/login/oauth2/code/hiauth-code
      scope: openid,profile

================================================
FILE: example/himall/src/main/resources/logback.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">

    <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
    <property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %level ${PID} [%thread] %logger %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}" />
    <!-- 彩色日志格式 -->
    <property name="LOG_PATTERN_COLORED" value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%level){blue} %clr(${PID}) %clr([%thread]){orange} %clr(%logger){cyan} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}" />
    <property name="LOG_FILE" value="himall.log"/>

    <!-- 彩色日志依赖的渲染类 -->
    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
    <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
    <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />

    <!-- 控制台输出 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <withJansi>false</withJansi>
        <encoder>
            <pattern>${LOG_PATTERN_COLORED}</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder>
            <pattern>${LOG_PATTERN}</pattern>
            <charset class="java.nio.charset.Charset">UTF-8</charset>
        </encoder>
        <file>${LOG_FILE}</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
            <fileNamePattern>${LOG_FILE}.%i.zip</fileNamePattern>
            <minIndex>1</minIndex>
            <maxIndex>10</maxIndex>
        </rollingPolicy>
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <MaxFileSize>100MB</MaxFileSize>
        </triggeringPolicy>
    </appender>

    <!-- 日志输出级别 -->
    <root level="INFO">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="FILE"/>
    </root>

</configuration>


================================================
FILE: example/himall/src/main/resources/static/css/index.css
================================================
/* Space out content a bit */
body {
  padding-top: 20px;
  padding-bottom: 20px;
}

/* Everything but the jumbotron gets side spacing for mobile first views */
.header,
.marketing,
.footer {
  padding-right: 15px;
  padding-left: 15px;
}

/* Custom page header */
.header {
  padding-bottom: 20px;
  border-bottom: 1px solid #e5e5e5;
}
/* Make the masthead heading the same height as the navigation */
.header h3 {
  margin-top: 0;
  margin-bottom: 0;
  line-height: 40px;
}

/* Custom page footer */
.footer {
  padding-top: 19px;
  color: #777;
  border-top: 1px solid #e5e5e5;
}

/* Customize container */
@media (min-width: 768px) {
  .container {
    max-width: 730px;
  }
}
.container-narrow > hr {
  margin: 30px 0;
}

/* Main marketing message and sign up button */
.jumbotron {
  text-align: center;
  border-bottom: 1px solid #e5e5e5;
}
.jumbotron .btn {
  padding: 14px 24px;
  font-size: 21px;
}

/* Supporting marketing content */
.marketing {
  margin: 40px 0;
}
.marketing p + h4 {
  margin-top: 28px;
}

/* Responsive: Portrait tablets and up */
@media screen and (min-width: 768px) {
  /* Remove the padding we set earlier */
  .header,
  .marketing,
  .footer {
    padding-right: 0;
    padding-left: 0;
  }
  /* Space out the masthead */
  .header {
    margin-bottom: 30px;
  }
  /* Remove the bottom border on the jumbotron for visual effect */
  .jumbotron {
    border-bottom: 0;
  }
}


================================================
FILE: example/himall/src/main/resources/templates/demo.html
================================================
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org" xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
    <head>
        <title>Spring Security OAuth 2.0 Sample</title>
        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <link th:rel="stylesheet" th:href="@{/webjars/bootstrap/3.3.7/css/bootstrap.min.css} ">
    </head>
    <body>
        <div th:fragment="header">
            <nav class="navbar navbar-default">
                <div class="container">
                    <div class="container-fluid">
                        <div class="navbar-collapse collapse" id="navbar">
                        </div>
                    </div>
                </div>
            </nav>
        </div>
        <div class="container">
            <div th:if="${error}" class="alert alert-danger alert-dismissible" role="alert">
                <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                <h4 th:text="${error}" class="text-center"></h4>
            </div>
            <div class="panel panel-default">
                <div class="panel-heading">
                    <h3 class="panel-title">Authorize the client using <span style="font-family:monospace">grant_type</span>:</h3>
                </div>
                <ul class="list-group">
                    <li class="list-group-item">
                        <a href="/authorize?grant_type=authorization_code" th:href="@{/authorize?grant_type=authorization_code}"><span style="font-size:medium">Authorization Code</span>&nbsp;&nbsp;<small class="text-muted">(Login to Spring Authorization Server using: user1/password)</small></a>
                    </li>
                    <li class="list-group-item">
                        <a href="/authorize?grant_type=client_credentials" th:href="@{/authorize?grant_type=client_credentials}"><span style="font-size:medium">Client Credentials</span></a>
                    </li>
                </ul>
                <div th:if="${messages}" class="panel-footer">
                    <h4>Messages:</h4>
                    <table class="table table-condensed">
                        <tbody>
                            <tr class="row" th:each="message : ${messages}">
                                <td th:text="${message}">message</td>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
        <script src="/webjars/jquery/jquery.min.js" th:src="@{/webjars/jquery/3.6.3/jquery.min.js}"></script>
        <script th:src="@{/webjars/bootstrap/3.3.7/js/bootstrap.min.js}"></script>
    </body>
</html>


================================================
FILE: example/himall/src/main/resources/templates/index.html
================================================
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <title>HiMall</title>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">
    <link rel="icon" th:href="@{/static/favicon.ico}">
    <link th:rel="stylesheet" th:href="@{/webjars/bootstrap/3.3.7/css/bootstrap.min.css} ">
    <link th:href="@{/static/css/index.css}" rel="stylesheet">
</head>
<body>

<div class="container">
    <div class="header clearfix">
        <nav>
            <ul class="nav nav-pills pull-right">
                <li role="presentation" class="active"><a th:href="@{/}">Home</a></li>
                <li role="presentation" th:if="${session.isAuth!=null ? session.isAuth : false}"><a th:href="@{/profile}">Profile</a></li>
                <li role="presentation" th:if="${session.isAuth!=null ? session.isAuth : false}"><a th:href="@{/api/client}">Client</a></li>
                <li role="presentation" th:if="${session.isAuth!=null ? !session.isAuth : true}"><a th:href="@{/profile}">Login</a></li>
                <li role="presentation" th:if="${session.isAuth!=null ? session.isAuth : false}"><a th:href="@{/user/logout}">Logout</a></li>
            </ul>
        </nav>
        <h3 class="text-muted">HIMALL</h3>
    </div>

    <div class="jumbotron">
        <h1>HiMall Example</h1>
        <p class="lead">This example is a quick exercise to illustrate how Integrate HiAuth by Oauth2, an integrated instance of microservices is also included here, so you can find some best practices.</p>
        <p><a class="btn btn-lg btn-success" href="https://github.com/bestaone/HiAuth" role="button">View HiMall docs</a></p>
    </div>

    <div class="row marketing">
        <div class="col-lg-6"></div>
        <div class="col-lg-6"></div>
    </div>

    <footer class="footer">
        <p>&copy; HiMall system for hiauth.com, by 码道功臣@webestar.cn</p>
    </footer>

</div>

<script th:src="@{/webjars/bootstrap/3.3.7/js/bootstrap.min.js}"></script>

</body>
</html>


================================================
FILE: example/himall/src/main/resources/templates/profile.html
================================================
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <title>HiMall</title>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">
    <link rel="icon" th:href="@{/static/favicon.ico}">
    <link th:rel="stylesheet" th:href="@{/webjars/bootstrap/3.3.7/css/bootstrap.min.css} ">
    <link th:href="@{/static/css/index.css}" rel="stylesheet">
</head>
<body>

<div class="container">
    <div class="header clearfix">
        <nav>
            <ul class="nav nav-pills pull-right">
                <li role="presentation"><a th:href="@{/}">Home</a></li>
                <li role="presentation" th:if="${session.isAuth!=null ? session.isAuth : false}" class="active"><a th:href="@{/profile}">Profile</a></li>
                <li role="presentation" th:if="${session.isAuth!=null ? session.isAuth : false}"><a th:href="@{/api/client}">Client</a></li>
                <li role="presentation" th:if="${session.isAuth!=null ? !session.isAuth : true}"><a th:href="@{/signin}">Login</a></li>
                <li role="presentation" th:if="${session.isAuth!=null ? session.isAuth : false}"><a th:href="@{/user/logout}">Logout</a></li>
            </ul>
        </nav>
        <h3 class="text-muted">HIMALL</h3>
    </div>

    <div style="margin-top: 30px;"><span class="glyphicon glyphicon-user" aria-hidden="true"></span> 用户信息</div>
    <div class="row">
        <div class="col-md-2 title">用户姓名:</div><div class="col-md-4 text" th:text="${name}"></div>
        <div class="col-md-2 title">用户账号:</div><div class="col-md-4 text" th:text="${username}"></div>
        <div class="col-md-2 title">手机号码:</div><div class="col-md-4 text" th:text="${tel}"></div>
        <div class="col-md-2 title">最近登录:</div><div class="col-md-4 text" th:text="${lastLoginTime}"></div>
    </div>

    <div style="margin-top: 30px;"><span class="glyphicon glyphicon-list-alt" aria-hidden="true"></span> 我的订单</div>
    <div class="row">
        <div class="col-md-2 title">订单编号:</div><div class="col-md-4 text" th:text="${orderNo}"></div>
        <div class="col-md-2 title">订单标题:</div><div class="col-md-4 text" th:text="${orderTitle}"></div>
        <div class="col-md-2 title">创建时间:</div><div class="col-md-4 text" th:text="${orderCreateTime}"></div>
        <div class="col-md-2 title">订单总额:</div><div class="col-md-4 text" th:text="${orderTotalAmount}"></div>
    </div>

    <div class="row" style="margin-top: 30px; padding: 0px 15px;">
        <div class="panel panel-default">
            <div class="panel-heading">商品列表</div>
            <table class="table">
                <thead>
                    <tr>
                        <th>#</th>
                        <th>商品名称</th>
                        <th>单价(元)</th>
                        <th>库存(个)</th>
                        <th>上架时间</th>
                    </tr>
                </thead>
                <tbody>
                    <tr th:each="goods,stat : ${goodsList}">
                        <th scope="row" th:text="${stat.index + 1}"></th>
                        <td th:text="${goods.title}"></td>
                        <td th:text="${goods.price}"></td>
                        <td th:text="${goods.amount}"></td>
                        <td th:text="${goods.createTime}"></td>
                    </tr>
                </tbody>
            </table>

        </div>
    </div>

    <footer class="footer">
        <p>&copy; HiMall system for hiauth.com, by 码道功臣@webestar.cn.</p>
    </footer>

</div>

<script th:src="@{/webjars/bootstrap/3.3.7/js/bootstrap.min.js}"></script>

</body>
</html>


================================================
FILE: example/resource/pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.4.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>cn.hiauth</groupId>
    <artifactId>resource</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>17</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
        </dependency>
        <dependency>
            <groupId>cn.webestar.scms</groupId>
            <artifactId>commons</artifactId>
            <version>1.2.0</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>


================================================
FILE: example/resource/src/main/java/cn/hiauth/resource/ResourceStarter.java
================================================
package cn.hiauth.resource;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ResourceStarter {

    public static void main(String[] args) {
        SpringApplication.run(ResourceStarter.class, args);
    }

}


================================================
FILE: example/resource/src/main/java/cn/hiauth/resource/config/ResourceServerConfig.java
================================================
package cn.hiauth.resource.config;

import cn.hiauth.resource.config.auth.SimpleAccessDeniedHandler;
import cn.hiauth.resource.config.auth.SimpleAuthenticationEntryPoint;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
@EnableMethodSecurity(jsr250Enabled = true, securedEnabled = true)
public class ResourceServerConfig {

    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .authorizeHttpRequests(authorize -> authorize
                        .requestMatchers("/unpapi/**").permitAll()
                        .anyRequest().authenticated()
                )
                .oauth2ResourceServer(oauth2ResourceServer -> oauth2ResourceServer
                        .jwt(Customizer.withDefaults())
                        .authenticationEntryPoint(new SimpleAuthenticationEntryPoint())
                        .accessDeniedHandler(new SimpleAccessDeniedHandler())
                );
        return http.build();
    }

}


================================================
FILE: example/resource/src/main/java/cn/hiauth/resource/config/auth/SimpleAccessDeniedHandler.java
================================================
package cn.hiauth.resource.config.auth;

import cn.hiauth.resource.utils.ResponseTools;
import cn.webestar.scms.commons.R;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.oauth2.server.resource.authentication.AbstractOAuth2TokenAuthenticationToken;
import org.springframework.security.web.access.AccessDeniedHandler;

import java.io.IOException;

public class SimpleAccessDeniedHandler implements AccessDeniedHandler {

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException exception) throws IOException, ServletException {
        if (request.getUserPrincipal() instanceof AbstractOAuth2TokenAuthenticationToken) {
            ResponseTools.write(response, R.fail(10403, "没有权限访问"));
        } else {
            ResponseTools.write(response, R.fail(10403, exception.getMessage()));
        }
    }

}


================================================
FILE: example/resource/src/main/java/cn/hiauth/resource/config/auth/SimpleAuthenticationEntryPoint.java
================================================
package cn.hiauth.resource.config.auth;

import cn.hiauth.resource.utils.ResponseTools;
import cn.webestar.scms.commons.R;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.server.resource.InvalidBearerTokenException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;

import java.io.IOException;

public class SimpleAuthenticationEntryPoint implements AuthenticationEntryPoint {

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
        if (exception instanceof InsufficientAuthenticationException) {
            String accept = request.getHeader("accept");
            if (accept.contains(MediaType.TEXT_HTML_VALUE)) {
                //如果是html请求类型,则返回登录页
                LoginUrlAuthenticationEntryPoint loginUrlAuthenticationEntryPoint = new LoginUrlAuthenticationEntryPoint("/login");
                loginUrlAuthenticationEntryPoint.commence(request, response, exception);
            } else {
                //如果是api请求类型,则返回json
                ResponseTools.write(response, R.fail(10401, "缺少访问令牌"));
            }
        } else if (exception instanceof InvalidBearerTokenException) {
            ResponseTools.write(response, R.fail(10401, "令牌无效或过期"));
        } else {
            ResponseTools.write(response, R.fail(10401, exception.getMessage()));
        }
    }

}


================================================
FILE: example/resource/src/main/java/cn/hiauth/resource/controller/IndexController.java
================================================
package cn.hiauth.resource.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class IndexController {

    @GetMapping("/")
    public String index() {
        return "index";
    }

}

================================================
FILE: example/resource/src/main/java/cn/hiauth/resource/controller/ProfileController.java
================================================
package cn.hiauth.resource.controller;

import cn.webestar.scms.commons.R;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@PreAuthorize("hasAuthority('SCOPE_profile')")
@RestController
@RequestMapping("/api/profile")
public class ProfileController {

    @GetMapping("/info")
    public R<String> info() {
        return R.success("profile:superman");
    }

}

================================================
FILE: example/resource/src/main/java/cn/hiauth/resource/controller/UnpapiController.java
================================================
package cn.hiauth.resource.controller;

import cn.webestar.scms.commons.R;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/unpapi")
public class UnpapiController {

    @GetMapping("/metadata")
    public R<Map<String, Object>> metadata() {
        Map<String, Object> data = new HashMap<>(5);
        data.put("name", "hiauth-resource");
        data.put("description", "hiauth-resource");
        data.put("version", "1.0.0");
        return R.success(data);
    }

}

================================================
FILE: example/resource/src/main/java/cn/hiauth/resource/controller/UserController.java
================================================
package cn.hiauth.resource.controller;

import cn.webestar.scms.commons.R;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@PreAuthorize("hasAuthority('SCOPE_user')")
@RestController
@RequestMapping("/api/user")
public class UserController {

    @GetMapping("/info")
    public R<String> info() {
        return R.success("user:zhangsan");
    }

}

================================================
FILE: example/resource/src/main/java/cn/hiauth/resource/utils/ResponseTools.java
================================================
package cn.hiauth.resource.utils;

import cn.webestar.scms.commons.R;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

public class ResponseTools {

    private static final ObjectMapper om = new ObjectMapper();

    static {
        om.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    }

    public static void write(HttpServletResponse response, R<?> r) throws IOException {
        // 设置响应头
        response.setStatus(HttpServletResponse.SC_OK);
        response.setContentType("application/json;charset=UTF-8");
        response.setCharacterEncoding("UTF-8");
        // 序列化并写入响应
        try {
            String jsonResponse = om.writeValueAsString(r);
            response.getWriter().write(jsonResponse);
            response.getWriter().flush();
        } catch (IOException e) {
            // 如果JSON序列化失败,使用简单文本响应
            response.setContentType("text/plain;charset=UTF-8");
            response.getWriter().write("错误处理失败: " + e.getMessage());
        }
    }

}

================================================
FILE: example/resource/src/main/resources/application.yml
================================================
server.port: 9002

logging.level:
  root: DEBUG

spring.jackson:
  default-property-inclusion: NON_NULL
  serialization:
    indent-output: true

spring.security.oauth2.resourceServer:
  jwt:
    issuerUri: http://auth.hiauth.cn
    jwkSetUri: ${spring.security.oauth2.resourceServer.jwt.issuerUri}/oauth2/jwks


================================================
FILE: example/resource/src/main/resources/logback.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">

    <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
    <property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %level ${PID} [%thread] %logger %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}" />
    <!-- 彩色日志格式 -->
    <property name="LOG_PATTERN_COLORED" value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%level){blue} %clr(${PID}) %clr([%thread]){orange} %clr(%logger){cyan} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}" />
    <property name="LOG_FILE" value="resource.log"/>

    <!-- 彩色日志依赖的渲染类 -->
    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
    <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
    <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />

    <!-- 控制台输出 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <withJansi>false</withJansi>
        <encoder>
            <pattern>${LOG_PATTERN_COLORED}</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder>
            <pattern>${LOG_PATTERN}</pattern>
            <charset class="java.nio.charset.Charset">UTF-8</charset>
        </encoder>
        <file>${LOG_FILE}</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
            <fileNamePattern>${LOG_FILE}.%i.zip</fileNamePattern>
            <minIndex>1</minIndex>
            <maxIndex>10</maxIndex>
        </rollingPolicy>
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <MaxFileSize>100MB</MaxFileSize>
        </triggeringPolicy>
    </appender>

    <!-- 日志输出级别 -->
    <root level="INFO">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="FILE"/>
    </root>

</configuration>


================================================
FILE: example/spring-cloud/README.md
================================================
- 访问:http://auth.hiauth.cn,如果是登录状态,先退出登录
- 然后访问:http://127.0.0.1:9000/ordersvc

================================================
FILE: example/spring-cloud/gateway/pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>cn.hiauth</groupId>
    <artifactId>gateway</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>gateway</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>17</java.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>3.3.10</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>2023.0.6</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2023.0.3.3</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <!-- 开发支持:热启动等 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!-- 网关 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <!--注册中心客户端-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
        <!-- OAuth2 Client -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-client</artifactId>
        </dependency>
        <!-- Spring Security -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>


================================================
FILE: example/spring-cloud/gateway/src/main/java/cn/hiauth/gateway/ApiController.java
================================================
package cn.hiauth.gateway;

import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/common")
public class ApiController {

    @GetMapping("/userinfo")
    public OAuth2User userinfo(OAuth2AuthenticationToken authentication) {
        return authentication.getPrincipal();
    }

}

================================================
FILE: example/spring-cloud/gateway/src/main/java/cn/hiauth/gateway/GatewayStarter.java
================================================
package cn.hiauth.gateway;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class GatewayStarter {

    public static void main(String[] args) {
        SpringApplication.run(GatewayStarter.class, args);
    }

}


================================================
FILE: example/spring-cloud/gateway/src/main/java/cn/hiauth/gateway/IndexController.java
================================================
package cn.hiauth.gateway;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class IndexController {

    @GetMapping("/")
    public String index() {
        return "gateway";
    }

    @GetMapping("/home")
    public String home() {
        return "home";
    }

}

================================================
FILE: example/spring-cloud/gateway/src/main/java/cn/hiauth/gateway/SecurityConfig.java
================================================
package cn.hiauth.gateway;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.web.server.WebFilterExchange;
import org.springframework.security.web.server.authentication.RedirectServerAuthenticationSuccessHandler;
import org.springframework.security.web.server.authentication.logout.LogoutWebFilter;
import org.springframework.security.web.server.authentication.logout.ServerLogoutSuccessHandler;
import org.springframework.security.web.server.authentication.logout.WebSessionServerLogoutHandler;
import reactor.core.publisher.Mono;

@Configuration
@EnableWebFluxSecurity
public class SecurityConfig {

    @Bean
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
        return http
                .authorizeExchange(exchanges -> exchanges
                        .pathMatchers("/login", "logout", "/oauth2/**").permitAll()
                        .anyExchange().authenticated()
                )
                .oauth2Login(oauth2 -> oauth2
                        .authenticationSuccessHandler(new RedirectServerAuthenticationSuccessHandler("/home"))
                )
                .logout(logout -> logout
                        .logoutUrl("/logout") // 退出登录端点
                        .logoutHandler(new WebSessionServerLogoutHandler()) // 清除会话
                        .logoutSuccessHandler(logoutSuccessHandler()) // 退出成功处理
                )
                .csrf(ServerHttpSecurity.CsrfSpec::disable)
                .build();
    }

    @Bean
    public ServerLogoutSuccessHandler logoutSuccessHandler() {
        return new ServerLogoutSuccessHandler() {
            @Override
            public Mono<Void> onLogoutSuccess(WebFilterExchange exchange, Authentication authentication) {
                // 重定向到登录页面或首页
                return Mono.fromRunnable(() -> {
                    exchange.getExchange().getResponse().setStatusCode(org.springframework.http.HttpStatus.FOUND);
                    exchange.getExchange().getResponse().getHeaders().setLocation(java.net.URI.create("/login?logout"));
                });
            }
        };
    }

    /**
     * 可选:添加自定义的LogoutWebFilter
     */
    @Bean
    public LogoutWebFilter logoutWebFilter() {
        return new LogoutWebFilter();
    }

}

================================================
FILE: example/spring-cloud/gateway/src/main/resources/application.yml
================================================
server.port: 9000
spring.application.name: gateway
logging.level.root: INFO

# Nacos注册中心配置
spring.cloud.nacos.discovery.server-addr: 192.168.1.250:8848

# 网关路由配置
spring.cloud.gateway.routes:
  - id: ordersvc
    uri: lb://ordersvc/
    predicates:
      - Path=/ordersvc/**
    filters:
      - StripPrefix=1
      - TokenRelay=

# oauth2客户端配置
spring.security.oauth2.client:
  provider:
    #认证服务器信息
    hiauth-server:
      # 如果你私有化部署了 HiAuth服务,请将此地址替换为私有部署的认证服务器地址
      issuer-uri: http://auth.hiauth.cn
      authorizationUri: ${spring.security.oauth2.client.provider.hiauth-server.issuer-uri}/oauth2/authorize
      #令牌获取地址
      tokenUri: ${spring.security.oauth2.client.provider.hiauth-server.issuer-uri}/oauth2/token
      userInfoUri: ${spring.security.oauth2.client.provider.hiauth-server.issuer-uri}/userinfo
      jwkSetUri: ${spring.security.oauth2.client.provider.hiauth-server.issuer-uri}/oauth2/jwks
      #userNameAttribute: name
  registration:
    hiauth-code:
      #认证提供者,标识由哪个认证服务器进行认证,和上面的hiauth-server进行关联
      provider: hiauth-server
      client-name: himall
      client-id: himall
      client-secret: secret
      #客户端认证方式 client_secret_basic\client_secret_post
      client-authentication-method: client_secret_basic
      #使用授权码模式获取令牌(token)
      authorization-grant-type: authorization_code
      # 认证完成后回调的地址,需要在数据库表oauth2_registered_client中登记这个地址,否则会拒绝回调
      redirect-uri: http://127.0.0.1:9000/login/oauth2/code/hiauth-code
      #redirect-uri: http://127.0.0.1:9000/home
      scope: openid,profile

================================================
FILE: example/spring-cloud/gateway/src/main/resources/logback.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">

    <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
    <property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %level ${PID} [%thread] %logger %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}" />
    <!-- 彩色日志格式 -->
    <property name="LOG_PATTERN_COLORED" value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%level){blue} %clr(${PID}) %clr([%thread]){orange} %clr(%logger){cyan} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}" />
    <property name="LOG_FILE" value="gateway.log"/>

    <!-- 彩色日志依赖的渲染类 -->
    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
    <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
    <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />

    <!-- 控制台输出 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <withJansi>false</withJansi>
        <encoder>
            <pattern>${LOG_PATTERN_COLORED}</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder>
            <pattern>${LOG_PATTERN}</pattern>
            <charset class="java.nio.charset.Charset">UTF-8</charset>
        </encoder>
        <file>${LOG_FILE}</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
            <fileNamePattern>${LOG_FILE}.%i.zip</fileNamePattern>
            <minIndex>1</minIndex>
            <maxIndex>10</maxIndex>
        </rollingPolicy>
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <MaxFileSize>100MB</MaxFileSize>
        </triggeringPolicy>
    </appender>

    <!-- 日志输出级别 -->
    <root level="INFO">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="FILE"/>
    </root>

</configuration>


================================================
FILE: example/spring-cloud/ordersvc/pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelV
Download .txt
gitextract_2zakr5hl/

├── .github/
│   └── workflows/
│       └── deploy.yml
├── .gitignore
├── LICENSE
├── README.md
├── cicd/
│   ├── Dockerfile
│   ├── Jenkinsfile
│   ├── hiauth.properties
│   └── nginx.conf
├── docs/
│   ├── .postcssrc.json
│   ├── .vitepress/
│   │   ├── config/
│   │   │   ├── en.ts
│   │   │   ├── index.ts
│   │   │   ├── shared.ts
│   │   │   └── zh.ts
│   │   └── theme/
│   │       ├── index.ts
│   │       └── styles.css
│   ├── en/
│   │   ├── guide/
│   │   │   ├── about-topic.md
│   │   │   ├── backend.md
│   │   │   ├── docker.md
│   │   │   ├── frontend.md
│   │   │   ├── hiauth-client.md
│   │   │   ├── issue.md
│   │   │   ├── k8s.md
│   │   │   ├── quick-start.md
│   │   │   ├── saas.md
│   │   │   ├── sourcecode.md
│   │   │   ├── test.md
│   │   │   └── what-is-hiauth.md
│   │   └── index.md
│   ├── lunaria.config.json
│   ├── package.json
│   ├── public/
│   │   ├── hiauth-logo-large.psd
│   │   └── pure.html
│   └── zh/
│       ├── guide/
│       │   ├── about-topic.md
│       │   ├── backend.md
│       │   ├── docker.md
│       │   ├── frontend.md
│       │   ├── hiauth-client.md
│       │   ├── issue.md
│       │   ├── k8s.md
│       │   ├── quick-start.md
│       │   ├── saas.md
│       │   ├── sourcecode.md
│       │   ├── test.md
│       │   └── what-is-hiauth.md
│       └── index.md
├── example/
│   ├── demo/
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── cn/
│   │           │       └── hiauth/
│   │           │           └── demo/
│   │           │               ├── DemoApplication.java
│   │           │               └── IndexController.java
│   │           └── resources/
│   │               └── application.yml
│   ├── hiauth-client/
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── cn/
│   │           │       └── hiauth/
│   │           │           └── hiauthclient/
│   │           │               ├── HiauthClientStarter.java
│   │           │               ├── config/
│   │           │               │   └── WebMvcConfig.java
│   │           │               └── controller/
│   │           │                   ├── ApiController.java
│   │           │                   └── IndexController.java
│   │           └── resources/
│   │               ├── application.yml
│   │               ├── logback.xml
│   │               ├── static/
│   │               │   └── css/
│   │               │       └── index.css
│   │               └── templates/
│   │                   ├── demo.html
│   │                   ├── index.html
│   │                   └── profile.html
│   ├── hiauth-client-exp/
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── cn/
│   │           │       └── hiauth/
│   │           │           └── client/
│   │           │               ├── ClientStarter.java
│   │           │               ├── config/
│   │           │               │   ├── BeanConfig.java
│   │           │               │   ├── SecurityConfig.java
│   │           │               │   └── WebMvcConfig.java
│   │           │               └── controller/
│   │           │                   └── ClientController.java
│   │           └── resources/
│   │               ├── application.yml
│   │               ├── logback.xml
│   │               └── templates/
│   │                   └── index.html
│   ├── hiauth-server-exp/
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── cn/
│   │           │       └── hiauth/
│   │           │           └── server/
│   │           │               ├── ServerStarter.java
│   │           │               ├── config/
│   │           │               │   ├── AuthServerConfig.java
│   │           │               │   ├── BeanConfig.java
│   │           │               │   ├── SecurityConfig.java
│   │           │               │   └── WebMvcConfig.java
│   │           │               ├── controller/
│   │           │               │   ├── IndexController.java
│   │           │               │   └── LoginController.java
│   │           │               ├── federation/
│   │           │               │   ├── FederatedIdentityAuthenticationSuccessHandler.java
│   │           │               │   └── FederatedIdentityIdTokenCustomizer.java
│   │           │               ├── mapper/
│   │           │               │   └── SimpleJdbcRegisteredClientRepository.java
│   │           │               └── utils/
│   │           │                   ├── jose/
│   │           │                   │   ├── Jwks.java
│   │           │                   │   └── KeyGeneratorUtils.java
│   │           │                   └── package-info.java
│   │           └── resources/
│   │               ├── application-hiauth.yml
│   │               ├── application-redis.yml
│   │               ├── application.yml
│   │               ├── logback.xml
│   │               └── templates/
│   │                   └── index.html
│   ├── himall/
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── cn/
│   │           │       └── hiauth/
│   │           │           └── himall/
│   │           │               ├── HiMallStarter.java
│   │           │               ├── config/
│   │           │               │   ├── SecurityConfig.java
│   │           │               │   └── WebMvcConfig.java
│   │           │               └── controller/
│   │           │                   ├── AuthController.java
│   │           │                   └── IndexController.java
│   │           └── resources/
│   │               ├── application.yml
│   │               ├── logback.xml
│   │               ├── static/
│   │               │   └── css/
│   │               │       └── index.css
│   │               └── templates/
│   │                   ├── demo.html
│   │                   ├── index.html
│   │                   └── profile.html
│   ├── resource/
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── cn/
│   │           │       └── hiauth/
│   │           │           └── resource/
│   │           │               ├── ResourceStarter.java
│   │           │               ├── config/
│   │           │               │   ├── ResourceServerConfig.java
│   │           │               │   └── auth/
│   │           │               │       ├── SimpleAccessDeniedHandler.java
│   │           │               │       └── SimpleAuthenticationEntryPoint.java
│   │           │               ├── controller/
│   │           │               │   ├── IndexController.java
│   │           │               │   ├── ProfileController.java
│   │           │               │   ├── UnpapiController.java
│   │           │               │   └── UserController.java
│   │           │               └── utils/
│   │           │                   └── ResponseTools.java
│   │           └── resources/
│   │               ├── application.yml
│   │               └── logback.xml
│   ├── spring-cloud/
│   │   ├── README.md
│   │   ├── gateway/
│   │   │   ├── pom.xml
│   │   │   └── src/
│   │   │       └── main/
│   │   │           ├── java/
│   │   │           │   └── cn/
│   │   │           │       └── hiauth/
│   │   │           │           └── gateway/
│   │   │           │               ├── ApiController.java
│   │   │           │               ├── GatewayStarter.java
│   │   │           │               ├── IndexController.java
│   │   │           │               └── SecurityConfig.java
│   │   │           └── resources/
│   │   │               ├── application.yml
│   │   │               └── logback.xml
│   │   ├── ordersvc/
│   │   │   ├── pom.xml
│   │   │   └── src/
│   │   │       └── main/
│   │   │           ├── java/
│   │   │           │   └── cn/
│   │   │           │       └── hiauth/
│   │   │           │           └── gateway/
│   │   │           │               ├── IndexController.java
│   │   │           │               └── OrderStarter.java
│   │   │           └── resources/
│   │   │               ├── application.yml
│   │   │               └── logback.xml
│   │   └── pom.xml
│   ├── spring-cloud-with-hiauth-client/
│   │   ├── README.md
│   │   ├── gateway1/
│   │   │   ├── pom.xml
│   │   │   └── src/
│   │   │       └── main/
│   │   │           ├── java/
│   │   │           │   └── cn/
│   │   │           │       └── hiauth/
│   │   │           │           └── gateway/
│   │   │           │               ├── ApiController.java
│   │   │           │               ├── GatewayStarter.java
│   │   │           │               └── IndexController.java
│   │   │           └── resources/
│   │   │               ├── application.yml
│   │   │               └── logback.xml
│   │   ├── ordersvc1/
│   │   │   ├── pom.xml
│   │   │   └── src/
│   │   │       └── main/
│   │   │           ├── java/
│   │   │           │   └── cn/
│   │   │           │       └── hiauth/
│   │   │           │           └── gateway/
│   │   │           │               ├── IndexController.java
│   │   │           │               └── OrderStarter.java
│   │   │           └── resources/
│   │   │               ├── application.yml
│   │   │               └── logback.xml
│   │   └── pom.xml
│   └── wechat-login/
│       ├── pom.xml
│       └── src/
│           └── main/
│               ├── java/
│               │   └── cn/
│               │       └── hiauth/
│               │           └── wechatlogin/
│               │               ├── WechatLoginStarter.java
│               │               ├── config/
│               │               │   ├── SecurityConfig.java
│               │               │   ├── WebMvcConfig.java
│               │               │   └── web/
│               │               │       ├── auth/
│               │               │       │   └── package-info.java
│               │               │       └── security/
│               │               │           ├── phone/
│               │               │           │   ├── SmsCodeAuthenticationFilter.java
│               │               │           │   ├── SmsCodeAuthenticationProvider.java
│               │               │           │   └── SmsCodeAuthenticationToken.java
│               │               │           └── wechat/
│               │               │               ├── QrCodeAuthenticationFilter.java
│               │               │               ├── QrCodeAuthenticationProvider.java
│               │               │               └── QrCodeAuthenticationToken.java
│               │               ├── controller/
│               │               │   ├── AuthController.java
│               │               │   └── IndexController.java
│               │               ├── entity/
│               │               │   └── CustomUserDetails.java
│               │               └── service/
│               │                   └── CustomUserDetailsService.java
│               └── resources/
│                   ├── application.yml
│                   ├── logback.xml
│                   └── templates/
│                       ├── home.html
│                       ├── index.html
│                       └── login.html
├── hiauth-client-starter/
│   ├── hiauth-client-commons/
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           └── java/
│   │               └── cn/
│   │                   └── hiauth/
│   │                       └── client/
│   │                           ├── Authentication.java
│   │                           ├── Client.java
│   │                           ├── Constant.java
│   │                           ├── HiAuthToken.java
│   │                           ├── JwtUtils.java
│   │                           ├── SecurityCorp.java
│   │                           ├── SecurityService.java
│   │                           ├── SecurityUser.java
│   │                           ├── SessionContext.java
│   │                           ├── SessionContextHolder.java
│   │                           ├── TokenVo.java
│   │                           └── UserinfoVo.java
│   ├── hiauth-client-resource-spring-boot-starter/
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── cn/
│   │           │       └── hiauth/
│   │           │           └── client/
│   │           │               └── resource/
│   │           │                   ├── HiAuthClientResourceAutoConfig.java
│   │           │                   └── HiAuthClientResourceProperties.java
│   │           └── resources/
│   │               └── META-INF/
│   │                   ├── spring-configuration-metadata.json
│   │                   └── spring.factories
│   ├── hiauth-client-session-spring-boot-starter/
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── cn/
│   │           │       └── hiauth/
│   │           │           └── client/
│   │           │               └── session/
│   │           │                   ├── AuthFilter.java
│   │           │                   ├── HiAuthClientSessionAutoConfig.java
│   │           │                   ├── HiAuthClientSessionCacheConfig.java
│   │           │                   ├── HiAuthClientSessionController.java
│   │           │                   ├── HiAuthClientSessionProperties.java
│   │           │                   └── HiAuthClientSessionRunner.java
│   │           └── resources/
│   │               └── META-INF/
│   │                   ├── spring-configuration-metadata.json
│   │                   └── spring.factories
│   ├── hiauth-client-spring-boot-starter/
│   │   ├── docs/
│   │   │   └── apisvc-oms.yml
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── cn/
│   │           │       └── hiauth/
│   │           │           └── client/
│   │           │               ├── AuthFilter.java
│   │           │               ├── HiAuthCacheConfig.java
│   │           │               ├── HiAuthClientAutoConfig.java
│   │           │               ├── HiAuthClientController.java
│   │           │               ├── HiAuthClientProperties.java
│   │           │               ├── HiAuthClientProviderProperties.java
│   │           │               ├── HiAuthClientRegistrationProperties.java
│   │           │               ├── HiAuthClientRunner.java
│   │           │               └── api/
│   │           │                   ├── TokenVo.java
│   │           │                   └── UserPwdUpdateDto.java
│   │           └── resources/
│   │               └── META-INF/
│   │                   ├── spring-configuration-metadata.json
│   │                   └── spring.factories
│   ├── hiauth-client-spring-cloud-gateway-starter/
│   │   ├── pom.xml
│   │   └── src/
│   │       └── main/
│   │           ├── java/
│   │           │   └── cn/
│   │           │       └── hiauth/
│   │           │           └── client/
│   │           │               └── gateway/
│   │           │                   ├── AuthGatewayFilterFactory.java
│   │           │                   ├── HiAuthClientGatewayAutoConfig.java
│   │           │                   ├── HiAuthClientGatewayController.java
│   │           │                   ├── HiAuthClientGatewayProperties.java
│   │           │                   ├── HiAuthClientGatewayRunner.java
│   │           │                   └── UserPwdUpdateDto.java
│   │           └── resources/
│   │               └── META-INF/
│   │                   ├── spring-configuration-metadata.json
│   │                   └── spring.factories
│   └── pom.xml
├── hiauth-front/
│   ├── .browserslistrc
│   ├── .changeset/
│   │   ├── README.md
│   │   └── config.json
│   ├── .commitlintrc.js
│   ├── .dockerignore
│   ├── .editorconfig
│   ├── .gitattributes
│   ├── .gitconfig
│   ├── .gitignore
│   ├── .gitpod.yml
│   ├── .node-version
│   ├── .npmrc
│   ├── .prettierignore
│   ├── .prettierrc.mjs
│   ├── .stylelintignore
│   ├── Dockerfile
│   ├── LICENSE
│   ├── README.ja-JP.md
│   ├── README.md
│   ├── README.zh-CN.md
│   ├── apps/
│   │   ├── backend-mock/
│   │   │   ├── README.md
│   │   │   ├── api/
│   │   │   │   ├── auth/
│   │   │   │   │   ├── codes.ts
│   │   │   │   │   ├── login.post.ts
│   │   │   │   │   ├── logout.post.ts
│   │   │   │   │   └── refresh.post.ts
│   │   │   │   ├── demo/
│   │   │   │   │   └── bigint.ts
│   │   │   │   ├── menu/
│   │   │   │   │   └── all.ts
│   │   │   │   ├── status.ts
│   │   │   │   ├── system/
│   │   │   │   │   ├── dept/
│   │   │   │   │   │   ├── .post.ts
│   │   │   │   │   │   ├── [id].delete.ts
│   │   │   │   │   │   ├── [id].put.ts
│   │   │   │   │   │   └── list.ts
│   │   │   │   │   ├── menu/
│   │   │   │   │   │   ├── list.ts
│   │   │   │   │   │   ├── name-exists.ts
│   │   │   │   │   │   └── path-exists.ts
│   │   │   │   │   └── role/
│   │   │   │   │       └── list.ts
│   │   │   │   ├── table/
│   │   │   │   │   └── list.ts
│   │   │   │   ├── test.get.ts
│   │   │   │   ├── test.post.ts
│   │   │   │   ├── upload.ts
│   │   │   │   └── user/
│   │   │   │       └── info.ts
│   │   │   ├── error.ts
│   │   │   ├── middleware/
│   │   │   │   └── 1.api.ts
│   │   │   ├── nitro.config.ts
│   │   │   ├── package.json
│   │   │   ├── routes/
│   │   │   │   └── [...].ts
│   │   │   ├── tsconfig.build.json
│   │   │   ├── tsconfig.json
│   │   │   └── utils/
│   │   │       ├── cookie-utils.ts
│   │   │       ├── jwt-utils.ts
│   │   │       ├── mock-data.ts
│   │   │       └── response.ts
│   │   ├── web-antd/
│   │   │   ├── index.html
│   │   │   ├── package.json
│   │   │   ├── postcss.config.mjs
│   │   │   ├── src/
│   │   │   │   ├── adapter/
│   │   │   │   │   ├── component/
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── form.ts
│   │   │   │   │   └── vxe-table.ts
│   │   │   │   ├── api/
│   │   │   │   │   ├── core/
│   │   │   │   │   │   ├── auth.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── menu.ts
│   │   │   │   │   │   └── user.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── request.ts
│   │   │   │   ├── app.vue
│   │   │   │   ├── bootstrap.ts
│   │   │   │   ├── layouts/
│   │   │   │   │   ├── auth.vue
│   │   │   │   │   ├── basic.vue
│   │   │   │   │   └── index.ts
│   │   │   │   ├── locales/
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── langs/
│   │   │   │   │       ├── en-US/
│   │   │   │   │       │   ├── demos.json
│   │   │   │   │       │   └── page.json
│   │   │   │   │       └── zh-CN/
│   │   │   │   │           ├── demos.json
│   │   │   │   │           └── page.json
│   │   │   │   ├── main.ts
│   │   │   │   ├── preferences.ts
│   │   │   │   ├── router/
│   │   │   │   │   ├── access.ts
│   │   │   │   │   ├── guard.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── routes/
│   │   │   │   │       ├── core.ts
│   │   │   │   │       ├── index.ts
│   │   │   │   │       └── modules/
│   │   │   │   │           ├── dashboard.ts
│   │   │   │   │           ├── demos.ts
│   │   │   │   │           └── vben.ts
│   │   │   │   ├── store/
│   │   │   │   │   ├── auth.ts
│   │   │   │   │   └── index.ts
│   │   │   │   └── views/
│   │   │   │       ├── _core/
│   │   │   │       │   ├── README.md
│   │   │   │       │   ├── about/
│   │   │   │       │   │   └── index.vue
│   │   │   │       │   ├── authentication/
│   │   │   │       │   │   ├── code-login.vue
│   │   │   │       │   │   ├── forget-password.vue
│   │   │   │       │   │   ├── login.vue
│   │   │   │       │   │   ├── qrcode-login.vue
│   │   │   │       │   │   └── register.vue
│   │   │   │       │   └── fallback/
│   │   │   │       │       ├── coming-soon.vue
│   │   │   │       │       ├── forbidden.vue
│   │   │   │       │       ├── internal-error.vue
│   │   │   │       │       ├── not-found.vue
│   │   │   │       │       └── offline.vue
│   │   │   │       ├── dashboard/
│   │   │   │       │   ├── analytics/
│   │   │   │       │   │   ├── analytics-trends.vue
│   │   │   │       │   │   ├── analytics-visits-data.vue
│   │   │   │       │   │   ├── analytics-visits-sales.vue
│   │   │   │       │   │   ├── analytics-visits-source.vue
│   │   │   │       │   │   ├── analytics-visits.vue
│   │   │   │       │   │   └── index.vue
│   │   │   │       │   └── workspace/
│   │   │   │       │       └── index.vue
│   │   │   │       └── demos/
│   │   │   │           └── antd/
│   │   │   │               └── index.vue
│   │   │   ├── tailwind.config.mjs
│   │   │   ├── tsconfig.json
│   │   │   ├── tsconfig.node.json
│   │   │   └── vite.config.mts
│   │   ├── web-auth/
│   │   │   ├── index.html
│   │   │   ├── package.json
│   │   │   ├── postcss.config.mjs
│   │   │   ├── src/
│   │   │   │   ├── adapter/
│   │   │   │   │   ├── component/
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── form.ts
│   │   │   │   │   └── vxe-table.ts
│   │   │   │   ├── api/
│   │   │   │   │   ├── core/
│   │   │   │   │   │   ├── app.ts
│   │   │   │   │   │   ├── appClient.ts
│   │   │   │   │   │   ├── appResource.ts
│   │   │   │   │   │   ├── auth.ts
│   │   │   │   │   │   ├── common.ts
│   │   │   │   │   │   ├── corp.ts
│   │   │   │   │   │   ├── dep.ts
│   │   │   │   │   │   ├── dict.ts
│   │   │   │   │   │   ├── emp.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── menu.ts
│   │   │   │   │   │   ├── role.ts
│   │   │   │   │   │   └── user.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── request.ts
│   │   │   │   ├── app.vue
│   │   │   │   ├── bootstrap.ts
│   │   │   │   ├── common/
│   │   │   │   │   ├── config.ts
│   │   │   │   │   ├── constants.ts
│   │   │   │   │   ├── context.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── types.ts
│   │   │   │   ├── layouts/
│   │   │   │   │   ├── auth.vue
│   │   │   │   │   ├── basic.vue
│   │   │   │   │   ├── change-corp.vue
│   │   │   │   │   ├── go-admin-space-button.vue
│   │   │   │   │   └── index.ts
│   │   │   │   ├── locales/
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── langs/
│   │   │   │   │       ├── en-US/
│   │   │   │   │       │   ├── demos.json
│   │   │   │   │       │   └── page.json
│   │   │   │   │       └── zh-CN/
│   │   │   │   │           ├── demos.json
│   │   │   │   │           └── page.json
│   │   │   │   ├── main.ts
│   │   │   │   ├── preferences.ts
│   │   │   │   ├── router/
│   │   │   │   │   ├── access.ts
│   │   │   │   │   ├── guard.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── routes/
│   │   │   │   │       ├── core.ts
│   │   │   │   │       ├── index.ts
│   │   │   │   │       └── modules/
│   │   │   │   │           ├── adminSpace.ts
│   │   │   │   │           ├── common.ts
│   │   │   │   │           ├── corpSpace.ts
│   │   │   │   │           └── dashboard.ts
│   │   │   │   ├── store/
│   │   │   │   │   ├── auth.ts
│   │   │   │   │   ├── content.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── utils/
│   │   │   │   │   └── rsa.ts
│   │   │   │   └── views/
│   │   │   │       ├── _core/
│   │   │   │       │   ├── README.md
│   │   │   │       │   ├── about/
│   │   │   │       │   │   └── index.vue
│   │   │   │       │   ├── authentication/
│   │   │   │       │   │   ├── code-login.vue
│   │   │   │       │   │   ├── forget-password.vue
│   │   │   │       │   │   ├── login.vue
│   │   │   │       │   │   ├── qrcode-login.vue
│   │   │   │       │   │   └── register.vue
│   │   │   │       │   └── fallback/
│   │   │   │       │       ├── coming-soon.vue
│   │   │   │       │       ├── forbidden.vue
│   │   │   │       │       ├── internal-error.vue
│   │   │   │       │       ├── not-found.vue
│   │   │   │       │       └── offline.vue
│   │   │   │       ├── adminSpace/
│   │   │   │       │   ├── corpMgr/
│   │   │   │       │   │   ├── corp-drawer.vue
│   │   │   │       │   │   └── index.vue
│   │   │   │       │   └── userMgr/
│   │   │   │       │       ├── index.vue
│   │   │   │       │       └── user-drawer.vue
│   │   │   │       ├── common/
│   │   │   │       │   ├── appMgr/
│   │   │   │       │   │   ├── app-drawer.vue
│   │   │   │       │   │   └── index.vue
│   │   │   │       │   └── appResourceMgr/
│   │   │   │       │       ├── app-resource-drawer.vue
│   │   │   │       │       └── index.vue
│   │   │   │       ├── corpSpace/
│   │   │   │       │   ├── appClientMgr/
│   │   │   │       │   │   ├── app-client-add-modal.vue
│   │   │   │       │   │   ├── app-client-drawer.vue
│   │   │   │       │   │   └── index.vue
│   │   │   │       │   ├── depMgr/
│   │   │   │       │   │   ├── dep-drawer.vue
│   │   │   │       │   │   └── index.vue
│   │   │   │       │   ├── empMgr/
│   │   │   │       │   │   ├── emp-drawer.vue
│   │   │   │       │   │   └── index.vue
│   │   │   │       │   ├── roleMgr/
│   │   │   │       │   │   ├── auth-modal.vue
│   │   │   │       │   │   ├── index.vue
│   │   │   │       │   │   └── role-drawer.vue
│   │   │   │       │   └── sysMgr/
│   │   │   │       │       └── dictMgr/
│   │   │   │       │           ├── dict-drawer.vue
│   │   │   │       │           └── index.vue
│   │   │   │       ├── dashboard/
│   │   │   │       │   ├── analytics/
│   │   │   │       │   │   ├── analytics-trends.vue
│   │   │   │       │   │   ├── analytics-visits-data.vue
│   │   │   │       │   │   ├── analytics-visits-sales.vue
│   │   │   │       │   │   ├── analytics-visits-source.vue
│   │   │   │       │   │   ├── analytics-visits.vue
│   │   │   │       │   │   └── index.vue
│   │   │   │       │   └── workspace/
│   │   │   │       │       └── index.vue
│   │   │   │       └── demos/
│   │   │   │           └── antd/
│   │   │   │               └── index.vue
│   │   │   ├── tailwind.config.mjs
│   │   │   ├── tsconfig.json
│   │   │   ├── tsconfig.node.json
│   │   │   └── vite.config.mts
│   │   ├── web-ele/
│   │   │   ├── index.html
│   │   │   ├── package.json
│   │   │   ├── postcss.config.mjs
│   │   │   ├── src/
│   │   │   │   ├── adapter/
│   │   │   │   │   ├── component/
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── form.ts
│   │   │   │   │   └── vxe-table.ts
│   │   │   │   ├── api/
│   │   │   │   │   ├── core/
│   │   │   │   │   │   ├── auth.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── menu.ts
│   │   │   │   │   │   └── user.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── request.ts
│   │   │   │   ├── app.vue
│   │   │   │   ├── bootstrap.ts
│   │   │   │   ├── layouts/
│   │   │   │   │   ├── auth.vue
│   │   │   │   │   ├── basic.vue
│   │   │   │   │   └── index.ts
│   │   │   │   ├── locales/
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── langs/
│   │   │   │   │       ├── en-US/
│   │   │   │   │       │   ├── demos.json
│   │   │   │   │       │   └── page.json
│   │   │   │   │       └── zh-CN/
│   │   │   │   │           ├── demos.json
│   │   │   │   │           └── page.json
│   │   │   │   ├── main.ts
│   │   │   │   ├── preferences.ts
│   │   │   │   ├── router/
│   │   │   │   │   ├── access.ts
│   │   │   │   │   ├── guard.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── routes/
│   │   │   │   │       ├── core.ts
│   │   │   │   │       ├── index.ts
│   │   │   │   │       └── modules/
│   │   │   │   │           ├── dashboard.ts
│   │   │   │   │           ├── demos.ts
│   │   │   │   │           └── vben.ts
│   │   │   │   ├── store/
│   │   │   │   │   ├── auth.ts
│   │   │   │   │   └── index.ts
│   │   │   │   └── views/
│   │   │   │       ├── _core/
│   │   │   │       │   ├── README.md
│   │   │   │       │   ├── about/
│   │   │   │       │   │   └── index.vue
│   │   │   │       │   ├── authentication/
│   │   │   │       │   │   ├── code-login.vue
│   │   │   │       │   │   ├── forget-password.vue
│   │   │   │       │   │   ├── login.vue
│   │   │   │       │   │   ├── qrcode-login.vue
│   │   │   │       │   │   └── register.vue
│   │   │   │       │   └── fallback/
│   │   │   │       │       ├── coming-soon.vue
│   │   │   │       │       ├── forbidden.vue
│   │   │   │       │       ├── internal-error.vue
│   │   │   │       │       ├── not-found.vue
│   │   │   │       │       └── offline.vue
│   │   │   │       ├── dashboard/
│   │   │   │       │   ├── analytics/
│   │   │   │       │   │   ├── analytics-trends.vue
│   │   │   │       │   │   ├── analytics-visits-data.vue
│   │   │   │       │   │   ├── analytics-visits-sales.vue
│   │   │   │       │   │   ├── analytics-visits-source.vue
│   │   │   │       │   │   ├── analytics-visits.vue
│   │   │   │       │   │   └── index.vue
│   │   │   │       │   └── workspace/
│   │   │   │       │       └── index.vue
│   │   │   │       └── demos/
│   │   │   │           ├── element/
│   │   │   │           │   └── index.vue
│   │   │   │           └── form/
│   │   │   │               └── basic.vue
│   │   │   ├── tailwind.config.mjs
│   │   │   ├── tsconfig.json
│   │   │   ├── tsconfig.node.json
│   │   │   └── vite.config.mts
│   │   └── web-naive/
│   │       ├── index.html
│   │       ├── package.json
│   │       ├── postcss.config.mjs
│   │       ├── src/
│   │       │   ├── adapter/
│   │       │   │   ├── component/
│   │       │   │   │   └── index.ts
│   │       │   │   ├── form.ts
│   │       │   │   ├── naive.ts
│   │       │   │   └── vxe-table.ts
│   │       │   ├── api/
│   │       │   │   ├── core/
│   │       │   │   │   ├── auth.ts
│   │       │   │   │   ├── index.ts
│   │       │   │   │   ├── menu.ts
│   │       │   │   │   └── user.ts
│   │       │   │   ├── index.ts
│   │       │   │   └── request.ts
│   │       │   ├── app.vue
│   │       │   ├── bootstrap.ts
│   │       │   ├── layouts/
│   │       │   │   ├── auth.vue
│   │       │   │   ├── basic.vue
│   │       │   │   └── index.ts
│   │       │   ├── locales/
│   │       │   │   ├── README.md
│   │       │   │   ├── index.ts
│   │       │   │   └── langs/
│   │       │   │       ├── en-US/
│   │       │   │       │   ├── demos.json
│   │       │   │       │   └── page.json
│   │       │   │       └── zh-CN/
│   │       │   │           ├── demos.json
│   │       │   │           └── page.json
│   │       │   ├── main.ts
│   │       │   ├── preferences.ts
│   │       │   ├── router/
│   │       │   │   ├── access.ts
│   │       │   │   ├── guard.ts
│   │       │   │   ├── index.ts
│   │       │   │   └── routes/
│   │       │   │       ├── core.ts
│   │       │   │       ├── index.ts
│   │       │   │       └── modules/
│   │       │   │           ├── dashboard.ts
│   │       │   │           ├── demos.ts
│   │       │   │           └── vben.ts
│   │       │   ├── store/
│   │       │   │   ├── auth.ts
│   │       │   │   └── index.ts
│   │       │   └── views/
│   │       │       ├── _core/
│   │       │       │   ├── README.md
│   │       │       │   ├── about/
│   │       │       │   │   └── index.vue
│   │       │       │   ├── authentication/
│   │       │       │   │   ├── code-login.vue
│   │       │       │   │   ├── forget-password.vue
│   │       │       │   │   ├── login.vue
│   │       │       │   │   ├── qrcode-login.vue
│   │       │       │   │   └── register.vue
│   │       │       │   └── fallback/
│   │       │       │       ├── coming-soon.vue
│   │       │       │       ├── forbidden.vue
│   │       │       │       ├── internal-error.vue
│   │       │       │       ├── not-found.vue
│   │       │       │       └── offline.vue
│   │       │       ├── dashboard/
│   │       │       │   ├── analytics/
│   │       │       │   │   ├── analytics-trends.vue
│   │       │       │   │   ├── analytics-visits-data.vue
│   │       │       │   │   ├── analytics-visits-sales.vue
│   │       │       │   │   ├── analytics-visits-source.vue
│   │       │       │   │   ├── analytics-visits.vue
│   │       │       │   │   └── index.vue
│   │       │       │   └── workspace/
│   │       │       │       └── index.vue
│   │       │       └── demos/
│   │       │           ├── form/
│   │       │           │   ├── basic.vue
│   │       │           │   └── modal.vue
│   │       │           ├── naive/
│   │       │           │   └── index.vue
│   │       │           └── table/
│   │       │               └── index.vue
│   │       ├── tailwind.config.mjs
│   │       ├── tsconfig.json
│   │       ├── tsconfig.node.json
│   │       └── vite.config.mts
│   ├── changlist.txt
│   ├── cspell.json
│   ├── deploy.yaml
│   ├── docs/
│   │   ├── .vitepress/
│   │   │   ├── components/
│   │   │   │   ├── demo-preview.vue
│   │   │   │   ├── index.ts
│   │   │   │   └── preview-group.vue
│   │   │   ├── config/
│   │   │   │   ├── en.mts
│   │   │   │   ├── index.mts
│   │   │   │   ├── plugins/
│   │   │   │   │   └── demo-preview.ts
│   │   │   │   ├── shared.mts
│   │   │   │   └── zh.mts
│   │   │   └── theme/
│   │   │       ├── components/
│   │   │       │   ├── site-layout.vue
│   │   │       │   └── vben-contributors.vue
│   │   │       ├── index.ts
│   │   │       ├── plugins/
│   │   │       │   └── hm.ts
│   │   │       └── styles/
│   │   │           ├── base.css
│   │   │           ├── index.ts
│   │   │           └── variables.css
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── _env/
│   │   │   │   ├── adapter/
│   │   │   │   │   ├── component.ts
│   │   │   │   │   ├── form.ts
│   │   │   │   │   └── vxe-table.ts
│   │   │   │   └── node/
│   │   │   │       └── adapter/
│   │   │   │           ├── form.ts
│   │   │   │           └── vxe-table.ts
│   │   │   ├── commercial/
│   │   │   │   ├── community.md
│   │   │   │   ├── customized.md
│   │   │   │   └── technical-support.md
│   │   │   ├── components/
│   │   │   │   ├── common-ui/
│   │   │   │   │   ├── vben-alert.md
│   │   │   │   │   ├── vben-api-component.md
│   │   │   │   │   ├── vben-count-to-animator.md
│   │   │   │   │   ├── vben-drawer.md
│   │   │   │   │   ├── vben-ellipsis-text.md
│   │   │   │   │   ├── vben-form.md
│   │   │   │   │   ├── vben-modal.md
│   │   │   │   │   └── vben-vxe-table.md
│   │   │   │   ├── introduction.md
│   │   │   │   └── layout-ui/
│   │   │   │       └── page.md
│   │   │   ├── demos/
│   │   │   │   ├── vben-alert/
│   │   │   │   │   ├── alert/
│   │   │   │   │   │   └── index.vue
│   │   │   │   │   ├── confirm/
│   │   │   │   │   │   └── index.vue
│   │   │   │   │   └── prompt/
│   │   │   │   │       └── index.vue
│   │   │   │   ├── vben-api-component/
│   │   │   │   │   └── cascader/
│   │   │   │   │       └── index.vue
│   │   │   │   ├── vben-count-to-animator/
│   │   │   │   │   ├── basic/
│   │   │   │   │   │   └── index.vue
│   │   │   │   │   └── custom/
│   │   │   │   │       └── index.vue
│   │   │   │   ├── vben-drawer/
│   │   │   │   │   ├── auto-height/
│   │   │   │   │   │   ├── drawer.vue
│   │   │   │   │   │   └── index.vue
│   │   │   │   │   ├── basic/
│   │   │   │   │   │   └── index.vue
│   │   │   │   │   ├── dynamic/
│   │   │   │   │   │   ├── drawer.vue
│   │   │   │   │   │   └── index.vue
│   │   │   │   │   ├── extra/
│   │   │   │   │   │   ├── drawer.vue
│   │   │   │   │   │   └── index.vue
│   │   │   │   │   └── shared-data/
│   │   │   │   │       ├── drawer.vue
│   │   │   │   │       └── index.vue
│   │   │   │   ├── vben-ellipsis-text/
│   │   │   │   │   ├── auto-display/
│   │   │   │   │   │   └── index.vue
│   │   │   │   │   ├── expand/
│   │   │   │   │   │   └── index.vue
│   │   │   │   │   ├── line/
│   │   │   │   │   │   └── index.vue
│   │   │   │   │   └── tooltip/
│   │   │   │   │       └── index.vue
│   │   │   │   ├── vben-form/
│   │   │   │   │   ├── api/
│   │   │   │   │   │   └── index.vue
│   │   │   │   │   ├── basic/
│   │   │   │   │   │   └── index.vue
│   │   │   │   │   ├── custom/
│   │   │   │   │   │   └── index.vue
│   │   │   │   │   ├── dynamic/
│   │   │   │   │   │   └── index.vue
│   │   │   │   │   ├── query/
│   │   │   │   │   │   └── index.vue
│   │   │   │   │   └── rules/
│   │   │   │   │       └── index.vue
│   │   │   │   ├── vben-modal/
│   │   │   │   │   ├── animation-type/
│   │   │   │   │   │   └── index.vue
│   │   │   │   │   ├── auto-height/
│   │   │   │   │   │   ├── index.vue
│   │   │   │   │   │   └── modal.vue
│   │   │   │   │   ├── basic/
│   │   │   │   │   │   └── index.vue
│   │   │   │   │   ├── draggable/
│   │   │   │   │   │   ├── index.vue
│   │   │   │   │   │   └── modal.vue
│   │   │   │   │   ├── dynamic/
│   │   │   │   │   │   ├── index.vue
│   │   │   │   │   │   └── modal.vue
│   │   │   │   │   ├── extra/
│   │   │   │   │   │   ├── index.vue
│   │   │   │   │   │   └── modal.vue
│   │   │   │   │   └── shared-data/
│   │   │   │   │       ├── index.vue
│   │   │   │   │       └── modal.vue
│   │   │   │   └── vben-vxe-table/
│   │   │   │       ├── basic/
│   │   │   │       │   └── index.vue
│   │   │   │       ├── custom-cell/
│   │   │   │       │   └── index.vue
│   │   │   │       ├── edit-cell/
│   │   │   │       │   └── index.vue
│   │   │   │       ├── edit-row/
│   │   │   │       │   └── index.vue
│   │   │   │       ├── fixed/
│   │   │   │       │   └── index.vue
│   │   │   │       ├── form/
│   │   │   │       │   └── index.vue
│   │   │   │       ├── mock-api.ts
│   │   │   │       ├── remote/
│   │   │   │       │   └── index.vue
│   │   │   │       ├── table-data.ts
│   │   │   │       ├── tree/
│   │   │   │       │   └── index.vue
│   │   │   │       └── virtual/
│   │   │   │           └── index.vue
│   │   │   ├── en/
│   │   │   │   ├── guide/
│   │   │   │   │   ├── essentials/
│   │   │   │   │   │   ├── build.md
│   │   │   │   │   │   ├── concept.md
│   │   │   │   │   │   ├── development.md
│   │   │   │   │   │   ├── external-module.md
│   │   │   │   │   │   ├── icons.md
│   │   │   │   │   │   ├── route.md
│   │   │   │   │   │   ├── server.md
│   │   │   │   │   │   ├── settings.md
│   │   │   │   │   │   └── styles.md
│   │   │   │   │   ├── in-depth/
│   │   │   │   │   │   ├── access.md
│   │   │   │   │   │   ├── check-updates.md
│   │   │   │   │   │   ├── features.md
│   │   │   │   │   │   ├── layout.md
│   │   │   │   │   │   ├── loading.md
│   │   │   │   │   │   ├── locale.md
│   │   │   │   │   │   ├── login.md
│   │   │   │   │   │   ├── theme.md
│   │   │   │   │   │   └── ui-framework.md
│   │   │   │   │   ├── introduction/
│   │   │   │   │   │   ├── changelog.md
│   │   │   │   │   │   ├── quick-start.md
│   │   │   │   │   │   ├── roadmap.md
│   │   │   │   │   │   ├── thin.md
│   │   │   │   │   │   ├── vben.md
│   │   │   │   │   │   └── why.md
│   │   │   │   │   ├── other/
│   │   │   │   │   │   ├── faq.md
│   │   │   │   │   │   ├── project-update.md
│   │   │   │   │   │   └── remove-code.md
│   │   │   │   │   └── project/
│   │   │   │   │       ├── changeset.md
│   │   │   │   │       ├── cli.md
│   │   │   │   │       ├── dir.md
│   │   │   │   │       ├── standard.md
│   │   │   │   │       ├── tailwindcss.md
│   │   │   │   │       ├── test.md
│   │   │   │   │       └── vite.md
│   │   │   │   └── index.md
│   │   │   ├── friend-links/
│   │   │   │   └── index.md
│   │   │   ├── guide/
│   │   │   │   ├── essentials/
│   │   │   │   │   ├── build.md
│   │   │   │   │   ├── concept.md
│   │   │   │   │   ├── development.md
│   │   │   │   │   ├── external-module.md
│   │   │   │   │   ├── icons.md
│   │   │   │   │   ├── route.md
│   │   │   │   │   ├── server.md
│   │   │   │   │   ├── settings.md
│   │   │   │   │   └── styles.md
│   │   │   │   ├── in-depth/
│   │   │   │   │   ├── access.md
│   │   │   │   │   ├── check-updates.md
│   │   │   │   │   ├── features.md
│   │   │   │   │   ├── layout.md
│   │   │   │   │   ├── loading.md
│   │   │   │   │   ├── locale.md
│   │   │   │   │   ├── login.md
│   │   │   │   │   ├── theme.md
│   │   │   │   │   └── ui-framework.md
│   │   │   │   ├── introduction/
│   │   │   │   │   ├── changelog.md
│   │   │   │   │   ├── quick-start.md
│   │   │   │   │   ├── roadmap.md
│   │   │   │   │   ├── thin.md
│   │   │   │   │   ├── vben.md
│   │   │   │   │   └── why.md
│   │   │   │   ├── other/
│   │   │   │   │   ├── faq.md
│   │   │   │   │   ├── project-update.md
│   │   │   │   │   └── remove-code.md
│   │   │   │   └── project/
│   │   │   │       ├── changeset.md
│   │   │   │       ├── cli.md
│   │   │   │       ├── dir.md
│   │   │   │       ├── standard.md
│   │   │   │       ├── tailwindcss.md
│   │   │   │       ├── test.md
│   │   │   │       └── vite.md
│   │   │   ├── index.md
│   │   │   └── sponsor/
│   │   │       └── personal.md
│   │   ├── tailwind.config.mjs
│   │   └── tsconfig.json
│   ├── eslint.config.mjs
│   ├── internal/
│   │   ├── lint-configs/
│   │   │   ├── commitlint-config/
│   │   │   │   ├── index.mjs
│   │   │   │   └── package.json
│   │   │   ├── eslint-config/
│   │   │   │   ├── build.config.ts
│   │   │   │   ├── package.json
│   │   │   │   ├── src/
│   │   │   │   │   ├── configs/
│   │   │   │   │   │   ├── command.ts
│   │   │   │   │   │   ├── comments.ts
│   │   │   │   │   │   ├── disableds.ts
│   │   │   │   │   │   ├── ignores.ts
│   │   │   │   │   │   ├── import.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── javascript.ts
│   │   │   │   │   │   ├── jsdoc.ts
│   │   │   │   │   │   ├── jsonc.ts
│   │   │   │   │   │   ├── node.ts
│   │   │   │   │   │   ├── perfectionist.ts
│   │   │   │   │   │   ├── prettier.ts
│   │   │   │   │   │   ├── regexp.ts
│   │   │   │   │   │   ├── test.ts
│   │   │   │   │   │   ├── turbo.ts
│   │   │   │   │   │   ├── typescript.ts
│   │   │   │   │   │   ├── unicorn.ts
│   │   │   │   │   │   └── vue.ts
│   │   │   │   │   ├── custom-config.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── util.ts
│   │   │   │   └── tsconfig.json
│   │   │   ├── prettier-config/
│   │   │   │   ├── index.mjs
│   │   │   │   └── package.json
│   │   │   └── stylelint-config/
│   │   │       ├── index.mjs
│   │   │       └── package.json
│   │   ├── node-utils/
│   │   │   ├── build.config.ts
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── __tests__/
│   │   │   │   │   ├── hash.test.ts
│   │   │   │   │   └── path.test.ts
│   │   │   │   ├── constants.ts
│   │   │   │   ├── date.ts
│   │   │   │   ├── fs.ts
│   │   │   │   ├── git.ts
│   │   │   │   ├── hash.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── monorepo.ts
│   │   │   │   ├── path.ts
│   │   │   │   ├── prettier.ts
│   │   │   │   └── spinner.ts
│   │   │   └── tsconfig.json
│   │   ├── tailwind-config/
│   │   │   ├── build.config.ts
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── index.ts
│   │   │   │   ├── module.d.ts
│   │   │   │   ├── plugins/
│   │   │   │   │   └── entry.ts
│   │   │   │   └── postcss.config.ts
│   │   │   └── tsconfig.json
│   │   ├── tsconfig/
│   │   │   ├── base.json
│   │   │   ├── library.json
│   │   │   ├── node.json
│   │   │   ├── package.json
│   │   │   ├── web-app.json
│   │   │   └── web.json
│   │   └── vite-config/
│   │       ├── build.config.ts
│   │       ├── package.json
│   │       ├── src/
│   │       │   ├── config/
│   │       │   │   ├── application.ts
│   │       │   │   ├── common.ts
│   │       │   │   ├── index.ts
│   │       │   │   └── library.ts
│   │       │   ├── index.ts
│   │       │   ├── options.ts
│   │       │   ├── plugins/
│   │       │   │   ├── archiver.ts
│   │       │   │   ├── extra-app-config.ts
│   │       │   │   ├── importmap.ts
│   │       │   │   ├── index.ts
│   │       │   │   ├── inject-app-loading/
│   │       │   │   │   ├── README.md
│   │       │   │   │   ├── default-loading-antd.html
│   │       │   │   │   ├── default-loading.html
│   │       │   │   │   └── index.ts
│   │       │   │   ├── inject-metadata.ts
│   │       │   │   ├── license.ts
│   │       │   │   ├── nitro-mock.ts
│   │       │   │   ├── print.ts
│   │       │   │   └── vxe-table.ts
│   │       │   ├── typing.ts
│   │       │   └── utils/
│   │       │       └── env.ts
│   │       └── tsconfig.json
│   ├── package.json
│   ├── packages/
│   │   ├── @core/
│   │   │   ├── README.md
│   │   │   ├── base/
│   │   │   │   ├── README.md
│   │   │   │   ├── design/
│   │   │   │   │   ├── package.json
│   │   │   │   │   ├── src/
│   │   │   │   │   │   ├── css/
│   │   │   │   │   │   │   ├── global.css
│   │   │   │   │   │   │   ├── nprogress.css
│   │   │   │   │   │   │   ├── transition.css
│   │   │   │   │   │   │   └── ui.css
│   │   │   │   │   │   ├── design-tokens/
│   │   │   │   │   │   │   ├── dark.css
│   │   │   │   │   │   │   ├── default.css
│   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── scss-bem/
│   │   │   │   │   │       ├── bem.scss
│   │   │   │   │   │       └── constants.scss
│   │   │   │   │   ├── tsconfig.json
│   │   │   │   │   └── vite.config.mts
│   │   │   │   ├── icons/
│   │   │   │   │   ├── build.config.ts
│   │   │   │   │   ├── package.json
│   │   │   │   │   ├── src/
│   │   │   │   │   │   ├── create-icon.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── lucide.ts
│   │   │   │   │   └── tsconfig.json
│   │   │   │   ├── shared/
│   │   │   │   │   ├── build.config.ts
│   │   │   │   │   ├── package.json
│   │   │   │   │   ├── src/
│   │   │   │   │   │   ├── cache/
│   │   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   │   └── storage-manager.test.ts
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   ├── storage-manager.ts
│   │   │   │   │   │   │   └── types.ts
│   │   │   │   │   │   ├── color/
│   │   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   │   └── convert.test.ts
│   │   │   │   │   │   │   ├── color.ts
│   │   │   │   │   │   │   ├── convert.ts
│   │   │   │   │   │   │   ├── generator.ts
│   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   ├── constants/
│   │   │   │   │   │   │   ├── globals.ts
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   └── vben.ts
│   │   │   │   │   │   ├── global-state.ts
│   │   │   │   │   │   ├── store.ts
│   │   │   │   │   │   └── utils/
│   │   │   │   │   │       ├── __tests__/
│   │   │   │   │   │       │   ├── diff.test.ts
│   │   │   │   │   │       │   ├── dom.test.ts
│   │   │   │   │   │       │   ├── inference.test.ts
│   │   │   │   │   │       │   ├── letter.test.ts
│   │   │   │   │   │       │   ├── resources.test.ts
│   │   │   │   │   │       │   ├── state-handler.test.ts
│   │   │   │   │   │       │   ├── tree.test.ts
│   │   │   │   │   │       │   ├── unique.test.ts
│   │   │   │   │   │       │   ├── update-css-variables.test.ts
│   │   │   │   │   │       │   ├── util.test.ts
│   │   │   │   │   │       │   └── window.test.ts
│   │   │   │   │   │       ├── cn.ts
│   │   │   │   │   │       ├── date.ts
│   │   │   │   │   │       ├── diff.ts
│   │   │   │   │   │       ├── dom.ts
│   │   │   │   │   │       ├── download.ts
│   │   │   │   │   │       ├── index.ts
│   │   │   │   │   │       ├── inference.ts
│   │   │   │   │   │       ├── letter.ts
│   │   │   │   │   │       ├── merge.ts
│   │   │   │   │   │       ├── nprogress.ts
│   │   │   │   │   │       ├── resources.ts
│   │   │   │   │   │       ├── state-handler.ts
│   │   │   │   │   │       ├── to.ts
│   │   │   │   │   │       ├── tree.ts
│   │   │   │   │   │       ├── unique.ts
│   │   │   │   │   │       ├── update-css-variables.ts
│   │   │   │   │   │       ├── util.ts
│   │   │   │   │   │       └── window.ts
│   │   │   │   │   └── tsconfig.json
│   │   │   │   └── typings/
│   │   │   │       ├── build.config.ts
│   │   │   │       ├── package.json
│   │   │   │       ├── src/
│   │   │   │       │   ├── app.d.ts
│   │   │   │       │   ├── basic.d.ts
│   │   │   │       │   ├── helper.d.ts
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── menu-record.ts
│   │   │   │       │   ├── tabs.ts
│   │   │   │       │   └── vue-router.d.ts
│   │   │   │       ├── tsconfig.json
│   │   │   │       └── vue-router.d.ts
│   │   │   ├── composables/
│   │   │   │   ├── build.config.ts
│   │   │   │   ├── package.json
│   │   │   │   ├── src/
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   └── use-sortable.test.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── use-is-mobile.ts
│   │   │   │   │   ├── use-layout-style.ts
│   │   │   │   │   ├── use-namespace.ts
│   │   │   │   │   ├── use-priority-value.ts
│   │   │   │   │   ├── use-scroll-lock.ts
│   │   │   │   │   ├── use-simple-locale/
│   │   │   │   │   │   ├── README.md
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── messages.ts
│   │   │   │   │   └── use-sortable.ts
│   │   │   │   └── tsconfig.json
│   │   │   ├── preferences/
│   │   │   │   ├── __tests__/
│   │   │   │   │   ├── __snapshots__/
│   │   │   │   │   │   └── config.test.ts.snap
│   │   │   │   │   ├── config.test.ts
│   │   │   │   │   └── preferences.test.ts
│   │   │   │   ├── build.config.ts
│   │   │   │   ├── package.json
│   │   │   │   ├── src/
│   │   │   │   │   ├── config.ts
│   │   │   │   │   ├── constants.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── preferences.ts
│   │   │   │   │   ├── types.ts
│   │   │   │   │   ├── update-css-variables.ts
│   │   │   │   │   └── use-preferences.ts
│   │   │   │   └── tsconfig.json
│   │   │   └── ui-kit/
│   │   │       ├── README.md
│   │   │       ├── form-ui/
│   │   │       │   ├── __tests__/
│   │   │       │   │   └── form-api.test.ts
│   │   │       │   ├── build.config.ts
│   │   │       │   ├── package.json
│   │   │       │   ├── postcss.config.mjs
│   │   │       │   ├── src/
│   │   │       │   │   ├── components/
│   │   │       │   │   │   └── form-actions.vue
│   │   │       │   │   ├── config.ts
│   │   │       │   │   ├── form-api.ts
│   │   │       │   │   ├── form-render/
│   │   │       │   │   │   ├── context.ts
│   │   │       │   │   │   ├── dependencies.ts
│   │   │       │   │   │   ├── expandable.ts
│   │   │       │   │   │   ├── form-field.vue
│   │   │       │   │   │   ├── form-label.vue
│   │   │       │   │   │   ├── form.vue
│   │   │       │   │   │   ├── helper.ts
│   │   │       │   │   │   └── index.ts
│   │   │       │   │   ├── index.ts
│   │   │       │   │   ├── types.ts
│   │   │       │   │   ├── use-form-context.ts
│   │   │       │   │   ├── use-vben-form.ts
│   │   │       │   │   ├── vben-form.vue
│   │   │       │   │   └── vben-use-form.vue
│   │   │       │   ├── tailwind.config.mjs
│   │   │       │   └── tsconfig.json
│   │   │       ├── layout-ui/
│   │   │       │   ├── build.config.ts
│   │   │       │   ├── package.json
│   │   │       │   ├── postcss.config.mjs
│   │   │       │   ├── src/
│   │   │       │   │   ├── components/
│   │   │       │   │   │   ├── index.ts
│   │   │       │   │   │   ├── layout-content.vue
│   │   │       │   │   │   ├── layout-footer.vue
│   │   │       │   │   │   ├── layout-header.vue
│   │   │       │   │   │   ├── layout-sidebar.vue
│   │   │       │   │   │   ├── layout-tabbar.vue
│   │   │       │   │   │   └── widgets/
│   │   │       │   │   │       ├── index.ts
│   │   │       │   │   │       ├── sidebar-collapse-button.vue
│   │   │       │   │   │       └── sidebar-fixed-button.vue
│   │   │       │   │   ├── hooks/
│   │   │       │   │   │   └── use-layout.ts
│   │   │       │   │   ├── index.ts
│   │   │       │   │   ├── vben-layout.ts
│   │   │       │   │   └── vben-layout.vue
│   │   │       │   ├── tailwind.config.mjs
│   │   │       │   └── tsconfig.json
│   │   │       ├── menu-ui/
│   │   │       │   ├── README.md
│   │   │       │   ├── build.config.ts
│   │   │       │   ├── package.json
│   │   │       │   ├── postcss.config.mjs
│   │   │       │   ├── src/
│   │   │       │   │   ├── components/
│   │   │       │   │   │   ├── collapse-transition.vue
│   │   │       │   │   │   ├── index.ts
│   │   │       │   │   │   ├── menu-badge-dot.vue
│   │   │       │   │   │   ├── menu-badge.vue
│   │   │       │   │   │   ├── menu-item.vue
│   │   │       │   │   │   ├── menu.vue
│   │   │       │   │   │   ├── normal-menu/
│   │   │       │   │   │   │   ├── index.ts
│   │   │       │   │   │   │   ├── normal-menu.ts
│   │   │       │   │   │   │   └── normal-menu.vue
│   │   │       │   │   │   ├── sub-menu-content.vue
│   │   │       │   │   │   └── sub-menu.vue
│   │   │       │   │   ├── hooks/
│   │   │       │   │   │   ├── index.ts
│   │   │       │   │   │   ├── use-menu-context.ts
│   │   │       │   │   │   ├── use-menu-scroll.ts
│   │   │       │   │   │   └── use-menu.ts
│   │   │       │   │   ├── index.ts
│   │   │       │   │   ├── menu.vue
│   │   │       │   │   ├── sub-menu.vue
│   │   │       │   │   ├── types.ts
│   │   │       │   │   └── utils/
│   │   │       │   │       └── index.ts
│   │   │       │   ├── tailwind.config.mjs
│   │   │       │   └── tsconfig.json
│   │   │       ├── popup-ui/
│   │   │       │   ├── build.config.ts
│   │   │       │   ├── package.json
│   │   │       │   ├── postcss.config.mjs
│   │   │       │   ├── src/
│   │   │       │   │   ├── alert/
│   │   │       │   │   │   ├── AlertBuilder.ts
│   │   │       │   │   │   ├── alert.ts
│   │   │       │   │   │   ├── alert.vue
│   │   │       │   │   │   └── index.ts
│   │   │       │   │   ├── drawer/
│   │   │       │   │   │   ├── __tests__/
│   │   │       │   │   │   │   └── drawer-api.test.ts
│   │   │       │   │   │   ├── drawer-api.ts
│   │   │       │   │   │   ├── drawer.ts
│   │   │       │   │   │   ├── drawer.vue
│   │   │       │   │   │   ├── index.ts
│   │   │       │   │   │   └── use-drawer.ts
│   │   │       │   │   ├── index.ts
│   │   │       │   │   └── modal/
│   │   │       │   │       ├── __tests__/
│   │   │       │   │       │   └── modal-api.test.ts
│   │   │       │   │       ├── index.ts
│   │   │       │   │       ├── modal-api.ts
│   │   │       │   │       ├── modal.ts
│   │   │       │   │       ├── modal.vue
│   │   │       │   │       ├── use-modal-draggable.ts
│   │   │       │   │       └── use-modal.ts
│   │   │       │   ├── tailwind.config.mjs
│   │   │       │   └── tsconfig.json
│   │   │       ├── shadcn-ui/
│   │   │       │   ├── build.config.ts
│   │   │       │   ├── components.json
│   │   │       │   ├── package.json
│   │   │       │   ├── postcss.config.mjs
│   │   │       │   ├── src/
│   │   │       │   │   ├── components/
│   │   │       │   │   │   ├── avatar/
│   │   │       │   │   │   │   ├── avatar.vue
│   │   │       │   │   │   │   └── index.ts
│   │   │       │   │   │   ├── back-top/
│   │   │       │   │   │   │   ├── back-top.vue
│   │   │       │   │   │   │   ├── backtop.ts
│   │   │       │   │   │   │   ├── index.ts
│   │   │       │   │   │   │   └── use-backtop.ts
│   │   │       │   │   │   ├── breadcrumb/
│   │   │       │   │   │   │   ├── breadcrumb-background.vue
│   │   │       │   │   │   │   ├── breadcrumb-view.vue
│   │   │       │   │   │   │   ├── breadcrumb.vue
│   │   │       │   │   │   │   ├── index.ts
│   │   │       │   │   │   │   └── types.ts
│   │   │       │   │   │   ├── button/
│   │   │       │   │   │   │   ├── button-group.vue
│   │   │       │   │   │   │   ├── button.ts
│   │   │       │   │   │   │   ├── button.vue
│   │   │       │   │   │   │   ├── check-button-group.vue
│   │   │       │   │   │   │   ├── icon-button.vue
│   │   │       │   │   │   │   └── index.ts
│   │   │       │   │   │   ├── checkbox/
│   │   │       │   │   │   │   ├── checkbox.vue
│   │   │       │   │   │   │   └── index.ts
│   │   │       │   │   │   ├── context-menu/
│   │   │       │   │   │   │   ├── context-menu.vue
│   │   │       │   │   │   │   ├── index.ts
│   │   │       │   │   │   │   └── interface.ts
│   │   │       │   │   │   ├── count-to-animator/
│   │   │       │   │   │   │   ├── count-to-animator.vue
│   │   │       │   │   │   │   └── index.ts
│   │   │       │   │   │   ├── dropdown-menu/
│   │   │       │   │   │   │   ├── dropdown-menu.vue
│   │   │       │   │   │   │   ├── dropdown-radio-menu.vue
│   │   │       │   │   │   │   ├── index.ts
│   │   │       │   │   │   │   └── interface.ts
│   │   │       │   │   │   ├── expandable-arrow/
│   │   │       │   │   │   │   ├── expandable-arrow.vue
│   │   │       │   │   │   │   └── index.ts
│   │   │       │   │   │   ├── full-screen/
│   │   │       │   │   │   │   ├── full-screen.vue
│   │   │       │   │   │   │   └── index.ts
│   │   │       │   │   │   ├── hover-card/
│   │   │       │   │   │   │   ├── hover-card.vue
│   │   │       │   │   │   │   └── index.ts
│   │   │       │   │   │   ├── icon/
│   │   │       │   │   │   │   ├── icon.vue
│   │   │       │   │   │   │   └── index.ts
│   │   │       │   │   │   ├── index.ts
│   │   │       │   │   │   ├── input-password/
│   │   │       │   │   │   │   ├── index.ts
│   │   │       │   │   │   │   ├── input-password.vue
│   │   │       │   │   │   │   └── password-strength.vue
│   │   │       │   │   │   ├── logo/
│   │   │       │   │   │   │   ├── index.ts
│   │   │       │   │   │   │   └── logo.vue
│   │   │       │   │   │   ├── pin-input/
│   │   │       │   │   │   │   ├── index.ts
│   │   │       │   │   │   │   ├── input.vue
│   │   │       │   │   │   │   └── types.ts
│   │   │       │   │   │   ├── popover/
│   │   │       │   │   │   │   ├── index.ts
│   │   │       │   │   │   │   └── popover.vue
│   │   │       │   │   │   ├── render-content/
│   │   │       │   │   │   │   ├── index.ts
│   │   │       │   │   │   │   └── render-content.vue
│   │   │       │   │   │   ├── scrollbar/
│   │   │       │   │   │   │   ├── index.ts
│   │   │       │   │   │   │   └── scrollbar.vue
│   │   │       │   │   │   ├── segmented/
│   │   │       │   │   │   │   ├── index.ts
│   │   │       │   │   │   │   ├── segmented.vue
│   │   │       │   │   │   │   ├── tabs-indicator.vue
│   │   │       │   │   │   │   └── types.ts
│   │   │       │   │   │   ├── select/
│   │   │       │   │   │   │   ├── index.ts
│   │   │       │   │   │   │   └── select.vue
│   │   │       │   │   │   ├── spine-text/
│   │   │       │   │   │   │   ├── index.ts
│   │   │       │   │   │   │   └── spine-text.vue
│   │   │       │   │   │   ├── spinner/
│   │   │       │   │   │   │   ├── index.ts
│   │   │       │   │   │   │   ├── loading.vue
│   │   │       │   │   │   │   └── spinner.vue
│   │   │       │   │   │   └── tooltip/
│   │   │       │   │   │       ├── help-tooltip.vue
│   │   │       │   │   │       ├── index.ts
│   │   │       │   │   │       └── tooltip.vue
│   │   │       │   │   ├── index.ts
│   │   │       │   │   └── ui/
│   │   │       │   │       ├── accordion/
│   │   │       │   │       │   ├── Accordion.vue
│   │   │       │   │       │   ├── AccordionContent.vue
│   │   │       │   │       │   ├── AccordionItem.vue
│   │   │       │   │       │   ├── AccordionTrigger.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── alert-dialog/
│   │   │       │   │       │   ├── AlertDialog.vue
│   │   │       │   │       │   ├── AlertDialogAction.vue
│   │   │       │   │       │   ├── AlertDialogCancel.vue
│   │   │       │   │       │   ├── AlertDialogContent.vue
│   │   │       │   │       │   ├── AlertDialogDescription.vue
│   │   │       │   │       │   ├── AlertDialogOverlay.vue
│   │   │       │   │       │   ├── AlertDialogTitle.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── avatar/
│   │   │       │   │       │   ├── Avatar.vue
│   │   │       │   │       │   ├── AvatarFallback.vue
│   │   │       │   │       │   ├── AvatarImage.vue
│   │   │       │   │       │   ├── avatar.ts
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── badge/
│   │   │       │   │       │   ├── Badge.vue
│   │   │       │   │       │   ├── badge.ts
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── breadcrumb/
│   │   │       │   │       │   ├── Breadcrumb.vue
│   │   │       │   │       │   ├── BreadcrumbEllipsis.vue
│   │   │       │   │       │   ├── BreadcrumbItem.vue
│   │   │       │   │       │   ├── BreadcrumbLink.vue
│   │   │       │   │       │   ├── BreadcrumbList.vue
│   │   │       │   │       │   ├── BreadcrumbPage.vue
│   │   │       │   │       │   ├── BreadcrumbSeparator.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── button/
│   │   │       │   │       │   ├── Button.vue
│   │   │       │   │       │   ├── button.ts
│   │   │       │   │       │   ├── index.ts
│   │   │       │   │       │   └── types.ts
│   │   │       │   │       ├── card/
│   │   │       │   │       │   ├── Card.vue
│   │   │       │   │       │   ├── CardContent.vue
│   │   │       │   │       │   ├── CardDescription.vue
│   │   │       │   │       │   ├── CardFooter.vue
│   │   │       │   │       │   ├── CardHeader.vue
│   │   │       │   │       │   ├── CardTitle.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── checkbox/
│   │   │       │   │       │   ├── Checkbox.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── context-menu/
│   │   │       │   │       │   ├── ContextMenu.vue
│   │   │       │   │       │   ├── ContextMenuCheckboxItem.vue
│   │   │       │   │       │   ├── ContextMenuContent.vue
│   │   │       │   │       │   ├── ContextMenuGroup.vue
│   │   │       │   │       │   ├── ContextMenuItem.vue
│   │   │       │   │       │   ├── ContextMenuLabel.vue
│   │   │       │   │       │   ├── ContextMenuPortal.vue
│   │   │       │   │       │   ├── ContextMenuRadioGroup.vue
│   │   │       │   │       │   ├── ContextMenuRadioItem.vue
│   │   │       │   │       │   ├── ContextMenuSeparator.vue
│   │   │       │   │       │   ├── ContextMenuShortcut.vue
│   │   │       │   │       │   ├── ContextMenuSub.vue
│   │   │       │   │       │   ├── ContextMenuSubContent.vue
│   │   │       │   │       │   ├── ContextMenuSubTrigger.vue
│   │   │       │   │       │   ├── ContextMenuTrigger.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── dialog/
│   │   │       │   │       │   ├── Dialog.vue
│   │   │       │   │       │   ├── DialogClose.vue
│   │   │       │   │       │   ├── DialogContent.vue
│   │   │       │   │       │   ├── DialogDescription.vue
│   │   │       │   │       │   ├── DialogFooter.vue
│   │   │       │   │       │   ├── DialogHeader.vue
│   │   │       │   │       │   ├── DialogOverlay.vue
│   │   │       │   │       │   ├── DialogScrollContent.vue
│   │   │       │   │       │   ├── DialogTitle.vue
│   │   │       │   │       │   ├── DialogTrigger.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── dropdown-menu/
│   │   │       │   │       │   ├── DropdownMenu.vue
│   │   │       │   │       │   ├── DropdownMenuCheckboxItem.vue
│   │   │       │   │       │   ├── DropdownMenuContent.vue
│   │   │       │   │       │   ├── DropdownMenuGroup.vue
│   │   │       │   │       │   ├── DropdownMenuItem.vue
│   │   │       │   │       │   ├── DropdownMenuLabel.vue
│   │   │       │   │       │   ├── DropdownMenuRadioGroup.vue
│   │   │       │   │       │   ├── DropdownMenuRadioItem.vue
│   │   │       │   │       │   ├── DropdownMenuSeparator.vue
│   │   │       │   │       │   ├── DropdownMenuShortcut.vue
│   │   │       │   │       │   ├── DropdownMenuSub.vue
│   │   │       │   │       │   ├── DropdownMenuSubContent.vue
│   │   │       │   │       │   ├── DropdownMenuSubTrigger.vue
│   │   │       │   │       │   ├── DropdownMenuTrigger.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── form/
│   │   │       │   │       │   ├── FormControl.vue
│   │   │       │   │       │   ├── FormDescription.vue
│   │   │       │   │       │   ├── FormItem.vue
│   │   │       │   │       │   ├── FormLabel.vue
│   │   │       │   │       │   ├── FormMessage.vue
│   │   │       │   │       │   ├── index.ts
│   │   │       │   │       │   ├── injectionKeys.ts
│   │   │       │   │       │   └── useFormField.ts
│   │   │       │   │       ├── hover-card/
│   │   │       │   │       │   ├── HoverCard.vue
│   │   │       │   │       │   ├── HoverCardContent.vue
│   │   │       │   │       │   ├── HoverCardTrigger.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── index.ts
│   │   │       │   │       ├── input/
│   │   │       │   │       │   ├── Input.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── label/
│   │   │       │   │       │   ├── Label.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── number-field/
│   │   │       │   │       │   ├── NumberField.vue
│   │   │       │   │       │   ├── NumberFieldContent.vue
│   │   │       │   │       │   ├── NumberFieldDecrement.vue
│   │   │       │   │       │   ├── NumberFieldIncrement.vue
│   │   │       │   │       │   ├── NumberFieldInput.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── pagination/
│   │   │       │   │       │   ├── PaginationEllipsis.vue
│   │   │       │   │       │   ├── PaginationFirst.vue
│   │   │       │   │       │   ├── PaginationLast.vue
│   │   │       │   │       │   ├── PaginationNext.vue
│   │   │       │   │       │   ├── PaginationPrev.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── pin-input/
│   │   │       │   │       │   ├── PinInput.vue
│   │   │       │   │       │   ├── PinInputGroup.vue
│   │   │       │   │       │   ├── PinInputInput.vue
│   │   │       │   │       │   ├── PinInputSeparator.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── popover/
│   │   │       │   │       │   ├── Popover.vue
│   │   │       │   │       │   ├── PopoverContent.vue
│   │   │       │   │       │   ├── PopoverTrigger.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── radio-group/
│   │   │       │   │       │   ├── RadioGroup.vue
│   │   │       │   │       │   ├── RadioGroupItem.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── resizable/
│   │   │       │   │       │   ├── ResizableHandle.vue
│   │   │       │   │       │   ├── ResizablePanelGroup.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── scroll-area/
│   │   │       │   │       │   ├── ScrollArea.vue
│   │   │       │   │       │   ├── ScrollBar.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── select/
│   │   │       │   │       │   ├── Select.vue
│   │   │       │   │       │   ├── SelectContent.vue
│   │   │       │   │       │   ├── SelectGroup.vue
│   │   │       │   │       │   ├── SelectItem.vue
│   │   │       │   │       │   ├── SelectItemText.vue
│   │   │       │   │       │   ├── SelectLabel.vue
│   │   │       │   │       │   ├── SelectScrollDownButton.vue
│   │   │       │   │       │   ├── SelectScrollUpButton.vue
│   │   │       │   │       │   ├── SelectSeparator.vue
│   │   │       │   │       │   ├── SelectTrigger.vue
│   │   │       │   │       │   ├── SelectValue.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── separator/
│   │   │       │   │       │   ├── Separator.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── sheet/
│   │   │       │   │       │   ├── Sheet.vue
│   │   │       │   │       │   ├── SheetClose.vue
│   │   │       │   │       │   ├── SheetContent.vue
│   │   │       │   │       │   ├── SheetDescription.vue
│   │   │       │   │       │   ├── SheetFooter.vue
│   │   │       │   │       │   ├── SheetHeader.vue
│   │   │       │   │       │   ├── SheetOverlay.vue
│   │   │       │   │       │   ├── SheetTitle.vue
│   │   │       │   │       │   ├── SheetTrigger.vue
│   │   │       │   │       │   ├── index.ts
│   │   │       │   │       │   └── sheet.ts
│   │   │       │   │       ├── switch/
│   │   │       │   │       │   ├── Switch.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── tabs/
│   │   │       │   │       │   ├── Tabs.vue
│   │   │       │   │       │   ├── TabsContent.vue
│   │   │       │   │       │   ├── TabsList.vue
│   │   │       │   │       │   ├── TabsTrigger.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── textarea/
│   │   │       │   │       │   ├── Textarea.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── toggle/
│   │   │       │   │       │   ├── Toggle.vue
│   │   │       │   │       │   ├── index.ts
│   │   │       │   │       │   └── toggle.ts
│   │   │       │   │       ├── toggle-group/
│   │   │       │   │       │   ├── ToggleGroup.vue
│   │   │       │   │       │   ├── ToggleGroupItem.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       ├── tooltip/
│   │   │       │   │       │   ├── Tooltip.vue
│   │   │       │   │       │   ├── TooltipContent.vue
│   │   │       │   │       │   ├── TooltipProvider.vue
│   │   │       │   │       │   ├── TooltipTrigger.vue
│   │   │       │   │       │   └── index.ts
│   │   │       │   │       └── tree/
│   │   │       │   │           ├── index.ts
│   │   │       │   │           ├── tree.vue
│   │   │       │   │           └── types.ts
│   │   │       │   ├── tailwind.config.mjs
│   │   │       │   └── tsconfig.json
│   │   │       └── tabs-ui/
│   │   │           ├── build.config.ts
│   │   │           ├── package.json
│   │   │           ├── postcss.config.mjs
│   │   │           ├── src/
│   │   │           │   ├── components/
│   │   │           │   │   ├── index.ts
│   │   │           │   │   ├── tabs/
│   │   │           │   │   │   └── tabs.vue
│   │   │           │   │   ├── tabs-chrome/
│   │   │           │   │   │   └── tabs.vue
│   │   │           │   │   └── widgets/
│   │   │           │   │       ├── index.ts
│   │   │           │   │       ├── tool-more.vue
│   │   │           │   │       └── tool-screen.vue
│   │   │           │   ├── index.ts
│   │   │           │   ├── tabs-view.vue
│   │   │           │   ├── types.ts
│   │   │           │   ├── use-tabs-drag.ts
│   │   │           │   └── use-tabs-view-scroll.ts
│   │   │           ├── tailwind.config.mjs
│   │   │           └── tsconfig.json
│   │   ├── constants/
│   │   │   ├── README.md
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── core.ts
│   │   │   │   └── index.ts
│   │   │   └── tsconfig.json
│   │   ├── effects/
│   │   │   ├── README.md
│   │   │   ├── access/
│   │   │   │   ├── package.json
│   │   │   │   ├── src/
│   │   │   │   │   ├── access-control.vue
│   │   │   │   │   ├── accessible.ts
│   │   │   │   │   ├── directive.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── use-access.ts
│   │   │   │   └── tsconfig.json
│   │   │   ├── common-ui/
│   │   │   │   ├── package.json
│   │   │   │   ├── src/
│   │   │   │   │   ├── components/
│   │   │   │   │   │   ├── api-component/
│   │   │   │   │   │   │   ├── api-component.vue
│   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   ├── captcha/
│   │   │   │   │   │   │   ├── hooks/
│   │   │   │   │   │   │   │   └── useCaptchaPoints.ts
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   ├── point-selection-captcha/
│   │   │   │   │   │   │   │   ├── index.vue
│   │   │   │   │   │   │   │   └── point-selection-captcha-card.vue
│   │   │   │   │   │   │   ├── slider-captcha/
│   │   │   │   │   │   │   │   ├── index.vue
│   │   │   │   │   │   │   │   ├── slider-captcha-action.vue
│   │   │   │   │   │   │   │   ├── slider-captcha-bar.vue
│   │   │   │   │   │   │   │   └── slider-captcha-content.vue
│   │   │   │   │   │   │   ├── slider-rotate-captcha/
│   │   │   │   │   │   │   │   └── index.vue
│   │   │   │   │   │   │   ├── slider-translate-captcha/
│   │   │   │   │   │   │   │   └── index.vue
│   │   │   │   │   │   │   └── types.ts
│   │   │   │   │   │   ├── col-page/
│   │   │   │   │   │   │   ├── col-page.vue
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   └── types.ts
│   │   │   │   │   │   ├── count-to/
│   │   │   │   │   │   │   ├── count-to.vue
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   └── types.ts
│   │   │   │   │   │   ├── ellipsis-text/
│   │   │   │   │   │   │   ├── ellipsis-text.vue
│   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   ├── icon-picker/
│   │   │   │   │   │   │   ├── icon-picker.vue
│   │   │   │   │   │   │   ├── icons.ts
│   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── json-viewer/
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   ├── index.vue
│   │   │   │   │   │   │   ├── style.scss
│   │   │   │   │   │   │   └── types.ts
│   │   │   │   │   │   ├── loading/
│   │   │   │   │   │   │   ├── directive.ts
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   ├── loading.vue
│   │   │   │   │   │   │   └── spinner.vue
│   │   │   │   │   │   ├── page/
│   │   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   │   └── page.test.ts
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   ├── page.vue
│   │   │   │   │   │   │   └── types.ts
│   │   │   │   │   │   ├── resize/
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   └── resize.vue
│   │   │   │   │   │   ├── tippy/
│   │   │   │   │   │   │   ├── directive.ts
│   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   └── tree/
│   │   │   │   │   │       ├── index.ts
│   │   │   │   │   │       └── tree.vue
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── ui/
│   │   │   │   │       ├── about/
│   │   │   │   │       │   ├── about.ts
│   │   │   │   │       │   ├── about.vue
│   │   │   │   │       │   └── index.ts
│   │   │   │   │       ├── authentication/
│   │   │   │   │       │   ├── auth-title.vue
│   │   │   │   │       │   ├── code-login.vue
│   │   │   │   │       │   ├── dingding-login.vue
│   │   │   │   │       │   ├── forget-password.vue
│   │   │   │   │       │   ├── index.ts
│   │   │   │   │       │   ├── login-expired-modal.vue
│   │   │   │   │       │   ├── login.vue
│   │   │   │   │       │   ├── qrcode-login.vue
│   │   │   │   │       │   ├── register.vue
│   │   │   │   │       │   ├── third-party-login.vue
│   │   │   │   │       │   └── types.ts
│   │   │   │   │       ├── dashboard/
│   │   │   │   │       │   ├── analysis/
│   │   │   │   │       │   │   ├── analysis-chart-card.vue
│   │   │   │   │       │   │   ├── analysis-charts-tabs.vue
│   │   │   │   │       │   │   ├── analysis-overview.vue
│   │   │   │   │       │   │   └── index.ts
│   │   │   │   │       │   ├── index.ts
│   │   │   │   │       │   ├── typing.ts
│   │   │   │   │       │   └── workbench/
│   │   │   │   │       │       ├── index.ts
│   │   │   │   │       │       ├── workbench-header.vue
│   │   │   │   │       │       ├── workbench-project.vue
│   │   │   │   │       │       ├── workbench-quick-nav.vue
│   │   │   │   │       │       ├── workbench-todo.vue
│   │   │   │   │       │       └── workbench-trends.vue
│   │   │   │   │       ├── fallback/
│   │   │   │   │       │   ├── fallback.ts
│   │   │   │   │       │   ├── fallback.vue
│   │   │   │   │       │   ├── icons/
│   │   │   │   │       │   │   ├── icon-403.vue
│   │   │   │   │       │   │   ├── icon-404.vue
│   │   │   │   │       │   │   ├── icon-500.vue
│   │   │   │   │       │   │   ├── icon-coming-soon.vue
│   │   │   │   │       │   │   └── icon-offline.vue
│   │   │   │   │       │   └── index.ts
│   │   │   │   │       └── index.ts
│   │   │   │   └── tsconfig.json
│   │   │   ├── hooks/
│   │   │   │   ├── README.md
│   │   │   │   ├── package.json
│   │   │   │   ├── src/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── use-app-config.ts
│   │   │   │   │   ├── use-content-maximize.ts
│   │   │   │   │   ├── use-design-tokens.ts
│   │   │   │   │   ├── use-hover-toggle.ts
│   │   │   │   │   ├── use-pagination.ts
│   │   │   │   │   ├── use-refresh.ts
│   │   │   │   │   ├── use-tabs.ts
│   │   │   │   │   └── use-watermark.ts
│   │   │   │   └── tsconfig.json
│   │   │   ├── layouts/
│   │   │   │   ├── package.json
│   │   │   │   ├── src/
│   │   │   │   │   ├── authentication/
│   │   │   │   │   │   ├── authentication.vue
│   │   │   │   │   │   ├── form.vue
│   │   │   │   │   │   ├── icons/
│   │   │   │   │   │   │   └── slogan.vue
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── toolbar.vue
│   │   │   │   │   │   └── types.ts
│   │   │   │   │   ├── basic/
│   │   │   │   │   │   ├── README.md
│   │   │   │   │   │   ├── content/
│   │   │   │   │   │   │   ├── content-spinner.vue
│   │   │   │   │   │   │   ├── content.vue
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   └── use-content-spinner.ts
│   │   │   │   │   │   ├── copyright/
│   │   │   │   │   │   │   ├── copyright.vue
│   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   ├── footer/
│   │   │   │   │   │   │   ├── footer.vue
│   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   ├── header/
│   │   │   │   │   │   │   ├── header.vue
│   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── layout.vue
│   │   │   │   │   │   ├── menu/
│   │   │   │   │   │   │   ├── extra-menu.vue
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   ├── menu.vue
│   │   │   │   │   │   │   ├── mixed-menu.vue
│   │   │   │   │   │   │   ├── use-extra-menu.ts
│   │   │   │   │   │   │   ├── use-mixed-menu.ts
│   │   │   │   │   │   │   └── use-navigation.ts
│   │   │   │   │   │   └── tabbar/
│   │   │   │   │   │       ├── index.ts
│   │   │   │   │   │       ├── tabbar.vue
│   │   │   │   │   │       └── use-tabbar.ts
│   │   │   │   │   ├── iframe/
│   │   │   │   │   │   ├── iframe-router-view.vue
│   │   │   │   │   │   ├── iframe-view.vue
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── widgets/
│   │   │   │   │       ├── breadcrumb.vue
│   │   │   │   │       ├── check-updates/
│   │   │   │   │       │   ├── check-updates.vue
│   │   │   │   │       │   └── index.ts
│   │   │   │   │       ├── color-toggle.vue
│   │   │   │   │       ├── global-search/
│   │   │   │   │       │   ├── global-search.vue
│   │   │   │   │       │   ├── index.ts
│   │   │   │   │       │   └── search-panel.vue
│   │   │   │   │       ├── index.ts
│   │   │   │   │       ├── language-toggle.vue
│   │   │   │   │       ├── layout-toggle.vue
│   │   │   │   │       ├── lock-screen/
│   │   │   │   │       │   ├── index.ts
│   │   │   │   │       │   ├── lock-screen-modal.vue
│   │   │   │   │       │   └── lock-screen.vue
│   │   │   │   │       ├── notification/
│   │   │   │   │       │   ├── index.ts
│   │   │   │   │       │   ├── notification.vue
│   │   │   │   │       │   └── types.ts
│   │   │   │   │       ├── preferences/
│   │   │   │   │       │   ├── blocks/
│   │   │   │   │       │   │   ├── block.vue
│   │   │   │   │       │   │   ├── checkbox-item.vue
│   │   │   │   │       │   │   ├── general/
│   │   │   │   │       │   │   │   ├── animation.vue
│   │   │   │   │       │   │   │   └── general.vue
│   │   │   │   │       │   │   ├── index.ts
│   │   │   │   │       │   │   ├── input-item.vue
│   │   │   │   │       │   │   ├── layout/
│   │   │   │   │       │   │   │   ├── breadcrumb.vue
│   │   │   │   │       │   │   │   ├── content.vue
│   │   │   │   │       │   │   │   ├── copyright.vue
│   │   │   │   │       │   │   │   ├── footer.vue
│   │   │   │   │       │   │   │   ├── header.vue
│   │   │   │   │       │   │   │   ├── layout.vue
│   │   │   │   │       │   │   │   ├── navigation.vue
│   │   │   │   │       │   │   │   ├── sidebar.vue
│   │   │   │   │       │   │   │   ├── tabbar.vue
│   │   │   │   │       │   │   │   └── widget.vue
│   │   │   │   │       │   │   ├── number-field-item.vue
│   │   │   │   │       │   │   ├── select-item.vue
│   │   │   │   │       │   │   ├── shortcut-keys/
│   │   │   │   │       │   │   │   └── global.vue
│   │   │   │   │       │   │   ├── switch-item.vue
│   │   │   │   │       │   │   ├── theme/
│   │   │   │   │       │   │   │   ├── builtin.vue
│   │   │   │   │       │   │   │   ├── color-mode.vue
│   │   │   │   │       │   │   │   ├── radius.vue
│   │   │   │   │       │   │   │   └── theme.vue
│   │   │   │   │       │   │   └── toggle-item.vue
│   │   │   │   │       │   ├── icons/
│   │   │   │   │       │   │   ├── content-compact.vue
│   │   │   │   │       │   │   ├── full-content.vue
│   │   │   │   │       │   │   ├── header-mixed-nav.vue
│   │   │   │   │       │   │   ├── header-nav.vue
│   │   │   │   │       │   │   ├── header-sidebar-nav.vue
│   │   │   │   │       │   │   ├── index.ts
│   │   │   │   │       │   │   ├── mixed-nav.vue
│   │   │   │   │       │   │   ├── setting.vue
│   │   │   │   │       │   │   ├── sidebar-mixed-nav.vue
│   │   │   │   │       │   │   └── sidebar-nav.vue
│   │   │   │   │       │   ├── index.ts
│   │   │   │   │       │   ├── preferences-button.vue
│   │   │   │   │       │   ├── preferences-drawer.vue
│   │   │   │   │       │   ├── preferences.vue
│   │   │   │   │       │   └── use-open-preferences.ts
│   │   │   │   │       ├── theme-toggle/
│   │   │   │   │       │   ├── index.ts
│   │   │   │   │       │   ├── theme-button.vue
│   │   │   │   │       │   └── theme-toggle.vue
│   │   │   │   │       └── user-dropdown/
│   │   │   │   │           ├── index.ts
│   │   │   │   │           └── user-dropdown.vue
│   │   │   │   └── tsconfig.json
│   │   │   ├── plugins/
│   │   │   │   ├── README.md
│   │   │   │   ├── package.json
│   │   │   │   ├── src/
│   │   │   │   │   ├── echarts/
│   │   │   │   │   │   ├── echarts-ui.vue
│   │   │   │   │   │   ├── echarts.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── use-echarts.ts
│   │   │   │   │   ├── motion/
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── types.ts
│   │   │   │   │   └── vxe-table/
│   │   │   │   │       ├── api.ts
│   │   │   │   │       ├── extends.ts
│   │   │   │   │       ├── index.ts
│   │   │   │   │       ├── init.ts
│   │   │   │   │       ├── style.css
│   │   │   │   │       ├── types.ts
│   │   │   │   │       ├── use-vxe-grid.ts
│   │   │   │   │       └── use-vxe-grid.vue
│   │   │   │   └── tsconfig.json
│   │   │   └── request/
│   │   │       ├── package.json
│   │   │       ├── src/
│   │   │       │   ├── index.ts
│   │   │       │   └── request-client/
│   │   │       │       ├── index.ts
│   │   │       │       ├── modules/
│   │   │       │       │   ├── downloader.test.ts
│   │   │       │       │   ├── downloader.ts
│   │   │       │       │   ├── interceptor.ts
│   │   │       │       │   ├── sse.test.ts
│   │   │       │       │   ├── sse.ts
│   │   │       │       │   ├── uploader.test.ts
│   │   │       │       │   └── uploader.ts
│   │   │       │       ├── preset-interceptors.ts
│   │   │       │       ├── request-client.test.ts
│   │   │       │       ├── request-client.ts
│   │   │       │       └── types.ts
│   │   │       └── tsconfig.json
│   │   ├── icons/
│   │   │   ├── README.md
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── iconify/
│   │   │   │   │   └── index.ts
│   │   │   │   ├── icons/
│   │   │   │   │   └── empty-icon.vue
│   │   │   │   ├── index.ts
│   │   │   │   └── svg/
│   │   │   │       ├── index.ts
│   │   │   │       └── load.ts
│   │   │   └── tsconfig.json
│   │   ├── locales/
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── i18n.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── langs/
│   │   │   │   │   ├── en-US/
│   │   │   │   │   │   ├── authentication.json
│   │   │   │   │   │   ├── common.json
│   │   │   │   │   │   ├── preferences.json
│   │   │   │   │   │   └── ui.json
│   │   │   │   │   └── zh-CN/
│   │   │   │   │       ├── authentication.json
│   │   │   │   │       ├── common.json
│   │   │   │   │       ├── preferences.json
│   │   │   │   │       └── ui.json
│   │   │   │   └── typing.ts
│   │   │   └── tsconfig.json
│   │   ├── preferences/
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   └── index.ts
│   │   │   └── tsconfig.json
│   │   ├── stores/
│   │   │   ├── package.json
│   │   │   ├── shim-pinia.d.ts
│   │   │   ├── src/
│   │   │   │   ├── index.ts
│   │   │   │   ├── modules/
│   │   │   │   │   ├── access.test.ts
│   │   │   │   │   ├── access.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── tabbar.test.ts
│   │   │   │   │   ├── tabbar.ts
│   │   │   │   │   ├── user.test.ts
│   │   │   │   │   └── user.ts
│   │   │   │   └── setup.ts
│   │   │   └── tsconfig.json
│   │   ├── styles/
│   │   │   ├── README.md
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── antd/
│   │   │   │   │   └── index.css
│   │   │   │   ├── ele/
│   │   │   │   │   └── index.css
│   │   │   │   ├── global/
│   │   │   │   │   └── index.scss
│   │   │   │   ├── index.ts
│   │   │   │   └── naive/
│   │   │   │       └── index.css
│   │   │   └── tsconfig.json
│   │   ├── types/
│   │   │   ├── README.md
│   │   │   ├── global.d.ts
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── index.ts
│   │   │   │   └── user.ts
│   │   │   └── tsconfig.json
│   │   └── utils/
│   │       ├── README.md
│   │       ├── package.json
│   │       ├── src/
│   │       │   ├── helpers/
│   │       │   │   ├── __tests__/
│   │       │   │   │   ├── find-menu-by-path.test.ts
│   │       │   │   │   ├── generate-menus.test.ts
│   │       │   │   │   ├── generate-routes-frontend.test.ts
│   │       │   │   │   └── merge-route-modules.test.ts
│   │       │   │   ├── find-menu-by-path.ts
│   │       │   │   ├── generate-menus.ts
│   │       │   │   ├── generate-routes-backend.ts
│   │       │   │   ├── generate-routes-frontend.ts
│   │       │   │   ├── get-popup-container.ts
│   │       │   │   ├── index.ts
│   │       │   │   ├── merge-route-modules.ts
│   │       │   │   ├── reset-routes.ts
│   │       │   │   └── unmount-global-loading.ts
│   │       │   └── index.ts
│   │       └── tsconfig.json
│   ├── playground/
│   │   ├── __tests__/
│   │   │   └── e2e/
│   │   │       ├── auth-login.spec.ts
│   │   │       └── common/
│   │   │           └── auth.ts
│   │   ├── index.html
│   │   ├── package.json
│   │   ├── playwright.config.ts
│   │   ├── postcss.config.mjs
│   │   ├── src/
│   │   │   ├── adapter/
│   │   │   │   ├── component/
│   │   │   │   │   └── index.ts
│   │   │   │   ├── form.ts
│   │   │   │   └── vxe-table.ts
│   │   │   ├── api/
│   │   │   │   ├── core/
│   │   │   │   │   ├── auth.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── menu.ts
│   │   │   │   │   └── user.ts
│   │   │   │   ├── examples/
│   │   │   │   │   ├── download.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── json-bigint.ts
│   │   │   │   │   ├── params.ts
│   │   │   │   │   ├── status.ts
│   │   │   │   │   ├── table.ts
│   │   │   │   │   └── upload.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── request.ts
│   │   │   │   └── system/
│   │   │   │       ├── dept.ts
│   │   │   │       ├── index.ts
│   │   │   │       ├── menu.ts
│   │   │   │       └── role.ts
│   │   │   ├── app.vue
│   │   │   ├── bootstrap.ts
│   │   │   ├── layouts/
│   │   │   │   ├── auth.vue
│   │   │   │   ├── basic.vue
│   │   │   │   └── index.ts
│   │   │   ├── locales/
│   │   │   │   ├── README.md
│   │   │   │   ├── index.ts
│   │   │   │   └── langs/
│   │   │   │       ├── en-US/
│   │   │   │       │   ├── demos.json
│   │   │   │       │   ├── examples.json
│   │   │   │       │   ├── page.json
│   │   │   │       │   └── system.json
│   │   │   │       └── zh-CN/
│   │   │   │           ├── demos.json
│   │   │   │           ├── examples.json
│   │   │   │           ├── page.json
│   │   │   │           └── system.json
│   │   │   ├── main.ts
│   │   │   ├── preferences.ts
│   │   │   ├── router/
│   │   │   │   ├── access.ts
│   │   │   │   ├── guard.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── routes/
│   │   │   │       ├── core.ts
│   │   │   │       ├── index.ts
│   │   │   │       └── modules/
│   │   │   │           ├── dashboard.ts
│   │   │   │           ├── demos.ts
│   │   │   │           ├── examples.ts
│   │   │   │           ├── system.ts
│   │   │   │           └── vben.ts
│   │   │   ├── store/
│   │   │   │   ├── auth.ts
│   │   │   │   └── index.ts
│   │   │   └── views/
│   │   │       ├── _core/
│   │   │       │   ├── README.md
│   │   │       │   ├── about/
│   │   │       │   │   └── index.vue
│   │   │       │   ├── authentication/
│   │   │       │   │   ├── code-login.vue
│   │   │       │   │   ├── forget-password.vue
│   │   │       │   │   ├── login.vue
│   │   │       │   │   ├── qrcode-login.vue
│   │   │       │   │   └── register.vue
│   │   │       │   └── fallback/
│   │   │       │       ├── coming-soon.vue
│   │   │       │       ├── forbidden.vue
│   │   │       │       ├── internal-error.vue
│   │   │       │       ├── not-found.vue
│   │   │       │       └── offline.vue
│   │   │       ├── dashboard/
│   │   │       │   ├── analytics/
│   │   │       │   │   ├── analytics-trends.vue
│   │   │       │   │   ├── analytics-visits-data.vue
│   │   │       │   │   ├── analytics-visits-sales.vue
│   │   │       │   │   ├── analytics-visits-source.vue
│   │   │       │   │   ├── analytics-visits.vue
│   │   │       │   │   └── index.vue
│   │   │       │   └── workspace/
│   │   │       │       └── index.vue
│   │   │       ├── demos/
│   │   │       │   ├── access/
│   │   │       │   │   ├── admin-visible.vue
│   │   │       │   │   ├── button-control.vue
│   │   │       │   │   ├── index.vue
│   │   │       │   │   ├── menu-visible-403.vue
│   │   │       │   │   ├── super-visible.vue
│   │   │       │   │   └── user-visible.vue
│   │   │       │   ├── active-icon/
│   │   │       │   │   └── index.vue
│   │   │       │   ├── badge/
│   │   │       │   │   └── index.vue
│   │   │       │   ├── breadcrumb/
│   │   │       │   │   ├── lateral-detail.vue
│   │   │       │   │   ├── lateral.vue
│   │   │       │   │   └── level-detail.vue
│   │   │       │   ├── features/
│   │   │       │   │   ├── clipboard/
│   │   │       │   │   │   └── index.vue
│   │   │       │   │   ├── file-download/
│   │   │       │   │   │   ├── base64.ts
│   │   │       │   │   │   └── index.vue
│   │   │       │   │   ├── full-screen/
│   │   │       │   │   │   └── index.vue
│   │   │       │   │   ├── hide-menu-children/
│   │   │       │   │   │   ├── children.vue
│   │   │       │   │   │   └── parent.vue
│   │   │       │   │   ├── icons/
│   │   │       │   │   │   └── index.vue
│   │   │       │   │   ├── json-bigint/
│   │   │       │   │   │   └── index.vue
│   │   │       │   │   ├── login-expired/
│   │   │       │   │   │   └── index.vue
│   │   │       │   │   ├── menu-query/
│   │   │       │   │   │   └── index.vue
│   │   │       │   │   ├── new-window/
│   │   │       │   │   │   └── index.vue
│   │   │       │   │   ├── request-params-serializer/
│   │   │       │   │   │   └── index.vue
│   │   │       │   │   ├── tabs/
│   │   │       │   │   │   ├── index.vue
│   │   │       │   │   │   └── tab-detail.vue
│   │   │       │   │   ├── vue-query/
│   │   │       │   │   │   ├── concurrency-caching.vue
│   │   │       │   │   │   ├── index.vue
│   │   │       │   │   │   ├── infinite-queries.vue
│   │   │       │   │   │   ├── paginated-queries.vue
│   │   │       │   │   │   ├── query-retries.vue
│   │   │       │   │   │   └── typing.ts
│   │   │       │   │   └── watermark/
│   │   │       │   │       └── index.vue
│   │   │       │   └── nested/
│   │   │       │       ├── menu-1.vue
│   │   │       │       ├── menu-2-1.vue
│   │   │       │       ├── menu-3-1.vue
│   │   │       │       └── menu-3-2-1.vue
│   │   │       ├── examples/
│   │   │       │   ├── button-group/
│   │   │       │   │   └── index.vue
│   │   │       │   ├── captcha/
│   │   │       │   │   ├── point-selection-captcha.vue
│   │   │       │   │   ├── slider-captcha.vue
│   │   │       │   │   ├── slider-rotate-captcha.vue
│   │   │       │   │   └── slider-translate-captcha.vue
│   │   │       │   ├── count-to/
│   │   │       │   │   └── index.vue
│   │   │       │   ├── doc-button.vue
│   │   │       │   ├── drawer/
│   │   │       │   │   ├── auto-height-demo.vue
│   │   │       │   │   ├── base-demo.vue
│   │   │       │   │   ├── dynamic-demo.vue
│   │   │       │   │   ├── form-drawer-demo.vue
│   │   │       │   │   ├── in-content-demo.vue
│   │   │       │   │   ├── index.vue
│   │   │       │   │   └── shared-data-demo.vue
│   │   │       │   ├── ellipsis/
│   │   │       │   │   └── index.vue
│   │   │       │   ├── form/
│   │   │       │   │   ├── api.vue
│   │   │       │   │   ├── basic.vue
│   │   │       │   │   ├── custom-layout.vue
│   │   │       │   │   ├── custom.vue
│   │   │       │   │   ├── dynamic.vue
│   │   │       │   │   ├── merge.vue
│   │   │       │   │   ├── modules/
│   │   │       │   │   │   └── two-fields.vue
│   │   │       │   │   ├── query.vue
│   │   │       │   │   ├── rules.vue
│   │   │       │   │   └── scroll-to-error-test.vue
│   │   │       │   ├── json-viewer/
│   │   │       │   │   ├── data.ts
│   │   │       │   │   └── index.vue
│   │   │       │   ├── layout/
│   │   │       │   │   └── col-page.vue
│   │   │       │   ├── loading/
│   │   │       │   │   └── index.vue
│   │   │       │   ├── modal/
│   │   │       │   │   ├── auto-height-demo.vue
│   │   │       │   │   ├── base-demo.vue
│   │   │       │   │   ├── blur-demo.vue
│   │   │       │   │   ├── drag-demo.vue
│   │   │       │   │   ├── dynamic-demo.vue
│   │   │       │   │   ├── form-modal-demo.vue
│   │   │       │   │   ├── in-content-demo.vue
│   │   │       │   │   ├── index.vue
│   │   │       │   │   ├── nested-demo.vue
│   │   │       │   │   └── shared-data-demo.vue
│   │   │       │   ├── motion/
│   │   │       │   │   └── index.vue
│   │   │       │   ├── resize/
│   │   │       │   │   └── basic.vue
│   │   │       │   ├── tippy/
│   │   │       │   │   └── index.vue
│   │   │       │   └── vxe-table/
│   │   │       │       ├── basic.vue
│   │   │       │       ├── custom-cell.vue
│   │   │       │       ├── edit-cell.vue
│   │   │       │       ├── edit-row.vue
│   │   │       │       ├── fixed.vue
│   │   │       │       ├── form.vue
│   │   │       │       ├── remote.vue
│   │   │       │       ├── table-data.ts
│   │   │       │       ├── tree.vue
│   │   │       │       └── virtual.vue
│   │   │       └── system/
│   │   │           ├── dept/
│   │   │           │   ├── data.ts
│   │   │           │   ├── list.vue
│   │   │           │   └── modules/
│   │   │           │       └── form.vue
│   │   │           ├── menu/
│   │   │           │   ├── data.ts
│   │   │           │   ├── list.vue
│   │   │           │   └── modules/
│   │   │           │       └── form.vue
│   │   │           └── role/
│   │   │               ├── data.ts
│   │   │               ├── list.vue
│   │   │               └── modules/
│   │   │                   └── form.vue
│   │   ├── tailwind.config.mjs
│   │   ├── tsconfig.json
│   │   ├── tsconfig.node.json
│   │   └── vite.config.mts
│   ├── pnpm-workspace.yaml
│   ├── scripts/
│   │   ├── clean.mjs
│   │   ├── deploy/
│   │   │   ├── Dockerfile
│   │   │   ├── build-local-docker-image.sh
│   │   │   └── nginx.conf
│   │   ├── turbo-run/
│   │   │   ├── README.md
│   │   │   ├── bin/
│   │   │   │   └── turbo-run.mjs
│   │   │   ├── build.config.ts
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── index.ts
│   │   │   │   └── run.ts
│   │   │   └── tsconfig.json
│   │   └── vsh/
│   │       ├── README.md
│   │       ├── bin/
│   │       │   └── vsh.mjs
│   │       ├── build.config.ts
│   │       ├── package.json
│   │       ├── src/
│   │       │   ├── check-circular/
│   │       │   │   └── index.ts
│   │       │   ├── check-dep/
│   │       │   │   └── index.ts
│   │       │   ├── code-workspace/
│   │       │   │   └── index.ts
│   │       │   ├── index.ts
│   │       │   ├── lint/
│   │       │   │   └── index.ts
│   │       │   └── publint/
│   │       │       └── index.ts
│   │       └── tsconfig.json
│   ├── stylelint.config.mjs
│   ├── tea.yaml
│   ├── turbo.json
│   ├── vben-admin.code-workspace
│   ├── vitest.config.ts
│   └── vitest.workspace.ts
├── hiauth-server/
│   ├── pom.xml
│   └── src/
│       ├── main/
│       │   ├── java/
│       │   │   └── cn/
│       │   │       └── hiauth/
│       │   │           └── server/
│       │   │               ├── ServerStarter.java
│       │   │               ├── api/
│       │   │               │   ├── dto/
│       │   │               │   │   ├── KeywordPageUserDto.java
│       │   │               │   │   ├── PageDepDto.java
│       │   │               │   │   ├── PageEmpDto.java
│       │   │               │   │   ├── PageRoleDto.java
│       │   │               │   │   ├── RegisterDto.java
│       │   │               │   │   ├── app/
│       │   │               │   │   │   ├── AppCreateDto.java
│       │   │               │   │   │   ├── AppLimitDto.java
│       │   │               │   │   │   ├── AppPageDto.java
│       │   │               │   │   │   └── AppUpdateDto.java
│       │   │               │   │   ├── appClient/
│       │   │               │   │   │   ├── AppClientCreateDto.java
│       │   │               │   │   │   ├── AppClientDeleteDto.java
│       │   │               │   │   │   ├── AppClientLimitDto.java
│       │   │               │   │   │   ├── AppClientPageDto.java
│       │   │               │   │   │   └── AppClientUpdateDto.java
│       │   │               │   │   ├── appResource/
│       │   │               │   │   │   ├── AppResourceCreateDto.java
│       │   │               │   │   │   ├── AppResourcePageDto.java
│       │   │               │   │   │   ├── AppResourceUpdateDto.java
│       │   │               │   │   │   └── FindAppResourceIdsByRoleAndAppDto.java
│       │   │               │   │   ├── corp/
│       │   │               │   │   │   ├── CorpCreateDto.java
│       │   │               │   │   │   ├── CorpPageDto.java
│       │   │               │   │   │   └── CorpUpdateDto.java
│       │   │               │   │   ├── dep/
│       │   │               │   │   │   ├── DepCreateDto.java
│       │   │               │   │   │   ├── DepLimitDto.java
│       │   │               │   │   │   ├── DepPageDto.java
│       │   │               │   │   │   └── DepUpdateDto.java
│       │   │               │   │   ├── dict/
│       │   │               │   │   │   ├── DictCreateDto.java
│       │   │               │   │   │   ├── DictLimitDto.java
│       │   │               │   │   │   ├── DictPageDto.java
│       │   │               │   │   │   └── DictUpdateDto.java
│       │   │               │   │   ├── emp/
│       │   │               │   │   │   ├── EmpCreateDto.java
│       │   │               │   │   │   ├── EmpPageDto.java
│       │   │               │   │   │   └── EmpUpdateDto.java
│       │   │               │   │   ├── login/
│       │   │               │   │   │   ├── CaptchaVerifyDto.java
│       │   │               │   │   │   ├── SmsCodeDto.java
│       │   │               │   │   │   └── SmsCodeLoginDto.java
│       │   │               │   │   ├── role/
│       │   │               │   │   │   ├── RoleAuthDto.java
│       │   │               │   │   │   ├── RoleCreateDto.java
│       │   │               │   │   │   ├── RoleLimitDto.java
│       │   │               │   │   │   ├── RolePageDto.java
│       │   │               │   │   │   └── RoleUpdateDto.java
│       │   │               │   │   └── user/
│       │   │               │   │       ├── UserCreateDto.java
│       │   │               │   │       ├── UserLimitDto.java
│       │   │               │   │       ├── UserPageDto.java
│       │   │               │   │       ├── UserPwdUpdateDto.java
│       │   │               │   │       └── UserUpdateDto.java
│       │   │               │   └── vo/
│       │   │               │       ├── CommonTreeNodeVo.java
│       │   │               │       ├── CorpAppVo.java
│       │   │               │       ├── CorpResourceTreeNodeVo.java
│       │   │               │       ├── CorpVo.java
│       │   │               │       ├── CurrentLoginUserVo.java
│       │   │               │       ├── EmpVo.java
│       │   │               │       ├── IndexCorpAppVo.java
│       │   │               │       ├── SysMenuVo.java
│       │   │               │       └── UserVo.java
│       │   │               ├── config/
│       │   │               │   ├── AuthServerConfig.java
│       │   │               │   ├── BeanConfig.java
│       │   │               │   ├── DocConfig.java
│       │   │               │   ├── SecurityConfig.java
│       │   │               │   ├── WebMvcConfig.java
│       │   │               │   ├── props/
│       │   │               │   │   ├── AppProperties.java
│       │   │               │   │   └── WechatProperties.java
│       │   │               │   ├── rest/
│       │   │               │   │   ├── ApiExceptionAdvice.java
│       │   │               │   │   ├── ResourceAccessDeniedHandler.java
│       │   │               │   │   ├── ResourceApi.java
│       │   │               │   │   ├── ResourceAuthenticationEntryPoint.java
│       │   │               │   │   └── security/
│       │   │               │   │       ├── ApiFilter.java
│       │   │               │   │       ├── MySecurityUser.java
│       │   │               │   │       └── ReadonlyFilter.java
│       │   │               │   └── web/
│       │   │               │       ├── auth/
│       │   │               │       │   ├── AuthFailureHandler.java
│       │   │               │       │   ├── AuthGrantedAuthority.java
│       │   │               │       │   ├── AuthGrantedAuthorityDeserializer.java
│       │   │               │       │   ├── AuthGrantedAuthorityMixin.java
│       │   │               │       │   ├── AuthUser.java
│       │   │               │       │   ├── AuthUserDeserializer.java
│       │   │               │       │   ├── AuthUserMixin.java
│       │   │               │       │   ├── CustomAuthUserAttrs.java
│       │   │               │       │   ├── CustomAuthorizationResponseHandler.java
│       │   │               │       │   ├── CustomJdbcRegisteredClientRepository.java
│       │   │               │       │   ├── CustomOidcUserInfoMapper.java
│       │   │               │       │   └── FederatedIdentityIdTokenCustomizer.java
│       │   │               │       └── security/
│       │   │               │           ├── CaptchaFilter.java
│       │   │               │           ├── CustomAuthenticationFailureHandler.java
│       │   │               │           ├── CustomAuthenticationSuccessHandler.java
│       │   │               │           ├── CustomLoginUrlAuthenticationEntryPoint.java
│       │   │               │           ├── MultiAppHttpSessionRequestCache.java
│       │   │               │           ├── MultiAuthUserService.java
│       │   │               │           ├── MultiAuthenticationProvider.java
│       │   │               │           ├── account/
│       │   │               │           │   ├── AccountAuthenticationFilter.java
│       │   │               │           │   ├── AccountAuthenticationProvider.java
│       │   │               │           │   └── AccountAuthenticationToken.java
│       │   │               │           ├── phone/
│       │   │               │           │   ├── SmsCodeAuthenticationFilter.java
│       │   │               │           │   ├── SmsCodeAuthenticationProvider.java
│       │   │               │           │   └── SmsCodeAuthenticationToken.java
│       │   │               │           └── wechat/
│       │   │               │               ├── QrCodeAuthenticationFilter.java
│       │   │               │               ├── QrCodeAuthenticationProvider.java
│       │   │               │               └── QrCodeAuthenticationToken.java
│       │   │               ├── controller/
│       │   │               │   ├── AuthConsentController.java
│       │   │               │   ├── IndexController.java
│       │   │               │   ├── LoginController.java
│       │   │               │   ├── OauthController.java
│       │   │               │   ├── TestController.java
│       │   │               │   ├── UnpController.java
│       │   │               │   ├── adminspace/
│       │   │               │   │   ├── CorpMgrController.java
│       │   │               │   │   └── UserMgrController.java
│       │   │               │   ├── common/
│       │   │               │   │   ├── AppMgrController.java
│       │   │               │   │   ├── AppResourceMgrController.java
│       │   │               │   │   └── CommonController.java
│       │   │               │   └── corpspace/
│       │   │               │       ├── AppClientMgrController.java
│       │   │               │       ├── DepMgrController.java
│       │   │               │       ├── DictMgrController.java
│       │   │               │       ├── EmpMgrController.java
│       │   │               │       └── RoleMgrController.java
│       │   │               ├── entity/
│       │   │               │   ├── App.java
│       │   │               │   ├── AppResource.java
│       │   │               │   ├── AuthorizationConsent.java
│       │   │               │   ├── Corp.java
│       │   │               │   ├── CorpApp.java
│       │   │               │   ├── CorpAppInfo.java
│       │   │               │   ├── Department.java
│       │   │               │   ├── Dict.java
│       │   │               │   ├── Employee.java
│       │   │               │   ├── File.java
│       │   │               │   ├── Oauth2Authorization.java
│       │   │               │   ├── Oauth2AuthorizationConsent.java
│       │   │               │   ├── Oauth2RegisteredClient.java
│       │   │               │   ├── Role.java
│       │   │               │   ├── RoleAppResource.java
│       │   │               │   ├── SysLog.java
│       │   │               │   └── User.java
│       │   │               ├── mapper/
│       │   │               │   ├── AppMapper.java
│       │   │               │   ├── AppResourceMapper.java
│       │   │               │   ├── CorpAppMapper.java
│       │   │               │   ├── CorpMapper.java
│       │   │               │   ├── DepartmentMapper.java
│       │   │               │   ├── DictMapper.java
│       │   │               │   ├── EmployeeMapper.java
│       │   │               │   ├── FileMapper.java
│       │   │               │   ├── Oauth2AuthorizationConsentMapper.java
│       │   │               │   ├── Oauth2AuthorizationMapper.java
│       │   │               │   ├── Oauth2RegisteredClientMapper.java
│       │   │               │   ├── RoleAppResourceMapper.java
│       │   │               │   ├── RoleMapper.java
│       │   │               │   ├── SysLogMapper.java
│       │   │               │   └── UserMapper.java
│       │   │               ├── service/
│       │   │               │   ├── AppResourceService.java
│       │   │               │   ├── AppService.java
│       │   │               │   ├── CorpAppService.java
│       │   │               │   ├── CorpService.java
│       │   │               │   ├── DepartmentService.java
│       │   │               │   ├── DictService.java
│       │   │               │   ├── EmployeeService.java
│       │   │               │   ├── FileService.java
│       │   │               │   ├── Oauth2AuthorizationConsentService.java
│       │   │               │   ├── Oauth2AuthorizationService.java
│       │   │               │   ├── Oauth2RegisteredClientService.java
│       │   │               │   ├── RoleService.java
│       │   │               │   ├── SimpleSecurityService.java
│       │   │               │   ├── SysLogService.java
│       │   │               │   ├── UserService.java
│       │   │               │   └── impl/
│       │   │               │       ├── AppResourceServiceImpl.java
│       │   │               │       ├── AppServiceImpl.java
│       │   │               │       ├── CorpAppServiceImpl.java
│       │   │               │       ├── CorpServiceImpl.java
│       │   │               │       ├── DepartmentServiceImpl.java
│       │   │               │       ├── DictServiceImpl.java
│       │   │               │       ├── EmployeeServiceImpl.java
│       │   │               │       ├── FileServiceImpl.java
│       │   │               │       ├── Oauth2AuthorizationConsentServiceImpl.java
│       │   │               │       ├── Oauth2AuthorizationServiceImpl.java
│       │   │               │       ├── Oauth2RegisteredClientServiceImpl.java
│       │   │               │       ├── RoleServiceImpl.java
│       │   │               │       ├── SysLogServiceImpl.java
│       │   │               │       └── UserServiceImpl.java
│       │   │               └── utils/
│       │   │                   ├── AliyunSmsUtils.java
│       │   │                   ├── AppResourceUtils.java
│       │   │                   ├── Constant.java
│       │   │                   ├── DateTimeUtils.java
│       │   │                   ├── DepartmentUtils.java
│       │   │                   ├── Oauth2RegisteredClientUtils.java
│       │   │                   ├── RsaUtils.java
│       │   │                   ├── SmsUtils.java
│       │   │                   └── jose/
│       │   │                       ├── Jwks.java
│       │   │                       └── KeyGeneratorUtils.java
│       │   └── resources/
│       │       ├── application-common.yml
│       │       ├── application-doc.yml
│       │       ├── application-hiauth.yml
│       │       ├── application-mybatis.yml
│       │       ├── application-redis.yml
│       │       ├── application.yml
│       │       ├── logback.xml
│       │       ├── mapper/
│       │       │   ├── AppMapper.xml
│       │       │   ├── AppResourceMapper.xml
│       │       │   ├── CorpAppMapper.xml
│       │       │   ├── CorpMapper.xml
│       │       │   ├── DepartmentMapper.xml
│       │       │   ├── DictMapper.xml
│       │       │   ├── EmployeeMapper.xml
│       │       │   ├── FileMapper.xml
│       │       │   ├── Oauth2AuthorizationConsentMapper.xml
│       │       │   ├── Oauth2AuthorizationMapper.xml
│       │       │   ├── Oauth2RegisteredClientMapper.xml
│       │       │   ├── RoleMapper.xml
│       │       │   ├── SysLogMapper.xml
│       │       │   └── UserMapper.xml
│       │       ├── static/
│       │       │   ├── bootstrap-5.3.0/
│       │       │   │   ├── css/
│       │       │   │   │   ├── bootstrap.min.css
│       │       │   │   │   ├── bootstrap.min.css.map
│       │       │   │   │   ├── bootstrap.rtl.min.css
│       │       │   │   │   └── bootstrap.rtl.min.css.map
│       │       │   │   └── js/
│       │       │   │       ├── bootstrap.bundle.min.js
│       │       │   │       └── bootstrap.bundle.min.js.map
│       │       │   ├── css/
│       │       │   │   ├── all.min.css
│       │       │   │   ├── common.css
│       │       │   │   ├── fontawesome.min.css
│       │       │   │   ├── index.css
│       │       │   │   ├── jquery.treetable.css
│       │       │   │   ├── jquery.treetable.theme.default.css
│       │       │   │   ├── login.css
│       │       │   │   ├── login1.css
│       │       │   │   ├── login2.css
│       │       │   │   ├── login3.css
│       │       │   │   ├── navbar.css
│       │       │   │   └── user_me.css
│       │       │   ├── fontawesome-5.15.4/
│       │       │   │   └── css/
│       │       │   │       ├── all.css
│       │       │   │       ├── all.min.css
│       │       │   │       ├── brands.css
│       │       │   │       ├── brands.min.css
│       │       │   │       ├── fontawesome.css
│       │       │   │       ├── fontawesome.min.css
│       │       │   │       ├── regular.css
│       │       │   │       ├── regular.min.css
│       │       │   │       ├── solid.css
│       │       │   │       ├── solid.min.css
│       │       │   │       ├── svg-with-js.css
│       │       │   │       ├── svg-with-js.min.css
│       │       │   │       ├── v4-shims.css
│       │       │   │       └── v4-shims.min.css
│       │       │   ├── img/
│       │       │   │   └── logo.psd
│       │       │   └── js/
│       │       │       ├── depTree.js
│       │       │       ├── jquery.min.js
│       │       │       ├── jquery.treetable.js
│       │       │       ├── jquery.validate.min.js
│       │       │       ├── login.js
│       │       │       ├── particle.js
│       │       │       ├── sliderCaptcha.js
│       │       │       └── wxLogin.js
│       │       └── templates/
│       │           ├── common/
│       │           │   └── include.html
│       │           ├── consent.html
│       │           ├── consent_bak.html
│       │           ├── error/
│       │           │   ├── 401.html
│       │           │   ├── 403.html
│       │           │   ├── 404.html
│       │           │   ├── 500.html
│       │           │   └── unconsent.html
│       │           ├── index.html
│       │           ├── login.html
│       │           ├── login1.html
│       │           ├── login2.html
│       │           ├── login3.html
│       │           ├── oauth/
│       │           │   ├── oauth_approval.html
│       │           │   └── oauth_error.html
│       │           ├── profile.html
│       │           ├── setting.html
│       │           └── user/
│       │               ├── detail.html
│       │               ├── list.html
│       │               ├── me.html
│       │               └── user.html
│       └── test/
│           └── java/
│               └── cn/
│                   └── hiauth/
│                       └── server/
│                           ├── AuthServerTests.java
│                           ├── CustomJdbcRegisteredClientRepositoryTests.java
│                           ├── DefaultAuthorizationServerApplicationTests.java
│                           ├── DefaultAuthorizationServerConsentTests.java
│                           └── service/
│                               ├── AppResourceServiceTests.java
│                               ├── AppServiceTests.java
│                               ├── CorpServiceTests.java
│                               ├── DepartmentServiceTests.java
│                               ├── DictServiceTests.java
│                               ├── EmployeeServiceTests.java
│                               ├── FileServiceTests.java
│                               ├── Oauth2AuthorizationConsentServiceTests.java
│                               ├── Oauth2AuthorizationServiceTests.java
│                               ├── Oauth2RegisteredClientServiceTests.java
│                               ├── RoleServiceTests.java
│                               ├── SysLogServiceTests.java
│                               └── UserServiceTests.java
├── other/
│   └── hiauth.sql
└── pom.xml
Download .txt
Showing preview only (236K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (2497 symbols across 625 files)

FILE: docs/.vitepress/config/en.ts
  function nav (line 31) | function nav(): DefaultTheme.NavItem[] {
  function sidebarGuide (line 59) | function sidebarGuide(): DefaultTheme.SidebarItem[] {
  function sidebarOther (line 101) | function sidebarOther(): DefaultTheme.SidebarItem[] {

FILE: docs/.vitepress/config/shared.ts
  method postprocess (line 21) | postprocess(code) {
  method config (line 26) | config(md) {
  method transformItems (line 52) | transformItems(items) {

FILE: docs/.vitepress/config/zh.ts
  function nav (line 56) | function nav(): DefaultTheme.NavItem[] {
  function sidebarGuide (line 84) | function sidebarGuide(): DefaultTheme.SidebarItem[] {
  function sidebarOther (line 126) | function sidebarOther(): DefaultTheme.SidebarItem[] {

FILE: example/demo/src/main/java/cn/hiauth/demo/DemoApplication.java
  class DemoApplication (line 6) | @SpringBootApplication
    method main (line 9) | public static void main(String[] args) {

FILE: example/demo/src/main/java/cn/hiauth/demo/IndexController.java
  class IndexController (line 20) | @RestController
    method index (line 28) | @GetMapping("/")

FILE: example/hiauth-client-exp/src/main/java/cn/hiauth/client/ClientStarter.java
  class ClientStarter (line 6) | @SpringBootApplication
    method main (line 9) | public static void main(String[] args) {

FILE: example/hiauth-client-exp/src/main/java/cn/hiauth/client/config/BeanConfig.java
  class BeanConfig (line 5) | @Configuration

FILE: example/hiauth-client-exp/src/main/java/cn/hiauth/client/config/SecurityConfig.java
  class SecurityConfig (line 6) | @Configuration

FILE: example/hiauth-client-exp/src/main/java/cn/hiauth/client/config/WebMvcConfig.java
  class WebMvcConfig (line 11) | @Configuration
    method addResourceHandlers (line 17) | @Override

FILE: example/hiauth-client-exp/src/main/java/cn/hiauth/client/controller/ClientController.java
  class ClientController (line 5) | @Controller

FILE: example/hiauth-client/src/main/java/cn/hiauth/hiauthclient/HiauthClientStarter.java
  class HiauthClientStarter (line 7) | @ComponentScan(basePackages = {"cn.hiauth.client", "cn.hiauth.hiauthclie...
    method main (line 11) | public static void main(String[] args) {

FILE: example/hiauth-client/src/main/java/cn/hiauth/hiauthclient/config/WebMvcConfig.java
  class WebMvcConfig (line 10) | @Configuration
    method addResourceHandlers (line 13) | @Override

FILE: example/hiauth-client/src/main/java/cn/hiauth/hiauthclient/controller/ApiController.java
  class ApiController (line 13) | @Slf4j
    method getAuth (line 19) | @GetMapping("/getAuth")

FILE: example/hiauth-client/src/main/java/cn/hiauth/hiauthclient/controller/IndexController.java
  class IndexController (line 16) | @Slf4j
    method index (line 20) | @GetMapping({"/", "/index"})
    method profile (line 33) | @GetMapping("/api/profile")

FILE: example/hiauth-server-exp/src/main/java/cn/hiauth/server/ServerStarter.java
  class ServerStarter (line 8) | @ComponentScan(basePackages = {"cn.hiauth.server", Constant.SCMS_BASIC_P...
    method main (line 12) | public static void main(String[] args) {

FILE: example/hiauth-server-exp/src/main/java/cn/hiauth/server/config/AuthServerConfig.java
  class AuthServerConfig (line 31) | @Configuration(proxyBeanMethods = false)
    method authorizationServerSecurityFilterChain (line 38) | @Bean
    method registeredClientRepository (line 66) | @Bean
    method authorizationService (line 71) | @Bean
    method authorizationConsentService (line 76) | @Bean
    method idTokenCustomizer (line 81) | @Bean
    method jwkSource (line 86) | @Bean
    method jwtDecoder (line 93) | @Bean
    method authorizationServerSettings (line 98) | @Bean

FILE: example/hiauth-server-exp/src/main/java/cn/hiauth/server/config/BeanConfig.java
  class BeanConfig (line 6) | @Slf4j

FILE: example/hiauth-server-exp/src/main/java/cn/hiauth/server/config/SecurityConfig.java
  class SecurityConfig (line 21) | @EnableWebSecurity
    method defaultSecurityFilterChain (line 26) | @Bean
    method userDetailsService (line 38) | @Bean
    method authenticationSuccessHandler (line 48) | private AuthenticationSuccessHandler authenticationSuccessHandler() {
    method sessionRegistry (line 52) | @Bean
    method httpSessionEventPublisher (line 57) | @Bean

FILE: example/hiauth-server-exp/src/main/java/cn/hiauth/server/config/WebMvcConfig.java
  class WebMvcConfig (line 11) | @Configuration
    method addResourceHandlers (line 17) | @Override

FILE: example/hiauth-server-exp/src/main/java/cn/hiauth/server/controller/IndexController.java
  class IndexController (line 5) | @Controller

FILE: example/hiauth-server-exp/src/main/java/cn/hiauth/server/controller/LoginController.java
  class LoginController (line 6) | @Slf4j

FILE: example/hiauth-server-exp/src/main/java/cn/hiauth/server/federation/FederatedIdentityAuthenticationSuccessHandler.java
  class FederatedIdentityAuthenticationSuccessHandler (line 38) | public final class FederatedIdentityAuthenticationSuccessHandler impleme...
    method onAuthenticationSuccess (line 47) | @Override
    method setOAuth2UserHandler (line 60) | public void setOAuth2UserHandler(Consumer<OAuth2User> oauth2UserHandle...
    method setOidcUserHandler (line 64) | public void setOidcUserHandler(Consumer<OidcUser> oidcUserHandler) {

FILE: example/hiauth-server-exp/src/main/java/cn/hiauth/server/federation/FederatedIdentityIdTokenCustomizer.java
  class FederatedIdentityIdTokenCustomizer (line 36) | public final class FederatedIdentityIdTokenCustomizer implements OAuth2T...
    method customize (line 53) | @Override
    method extractClaims (line 70) | private Map<String, Object> extractClaims(Authentication principal) {

FILE: example/hiauth-server-exp/src/main/java/cn/hiauth/server/mapper/SimpleJdbcRegisteredClientRepository.java
  class SimpleJdbcRegisteredClientRepository (line 11) | public class SimpleJdbcRegisteredClientRepository extends JdbcRegistered...
    method SimpleJdbcRegisteredClientRepository (line 31) | public SimpleJdbcRegisteredClientRepository(JdbcOperations jdbcOperati...
    method findByClientIds (line 35) | public List<RegisteredClient> findByClientIds(Set<String> clientIds) {

FILE: example/hiauth-server-exp/src/main/java/cn/hiauth/server/utils/jose/Jwks.java
  class Jwks (line 35) | public final class Jwks {
    method Jwks (line 37) | private Jwks() {
    method generateRsa (line 40) | public static RSAKey generateRsa() {
    method generateEc (line 52) | public static ECKey generateEc() {
    method generateSecret (line 65) | public static OctetSequenceKey generateSecret() {

FILE: example/hiauth-server-exp/src/main/java/cn/hiauth/server/utils/jose/KeyGeneratorUtils.java
  class KeyGeneratorUtils (line 32) | final class KeyGeneratorUtils {
    method KeyGeneratorUtils (line 34) | private KeyGeneratorUtils() {
    method generateSecretKey (line 37) | static SecretKey generateSecretKey() {
    method generateRsaKey (line 47) | static KeyPair generateRsaKey() {
    method generateEcKey (line 59) | static KeyPair generateEcKey() {

FILE: example/himall/src/main/java/cn/hiauth/himall/HiMallStarter.java
  class HiMallStarter (line 6) | @SpringBootApplication
    method main (line 9) | public static void main(String[] args) {

FILE: example/himall/src/main/java/cn/hiauth/himall/config/SecurityConfig.java
  class SecurityConfig (line 15) | @EnableWebSecurity
    method restTemplate (line 19) | @Bean
    method webSecurityCustomizer (line 24) | @Bean
    method securityFilterChain (line 29) | @Bean

FILE: example/himall/src/main/java/cn/hiauth/himall/config/WebMvcConfig.java
  class WebMvcConfig (line 10) | @Configuration
    method addResourceHandlers (line 13) | @Override

FILE: example/himall/src/main/java/cn/hiauth/himall/controller/AuthController.java
  class AuthController (line 10) | @RestController
    method client (line 13) | @ResponseBody

FILE: example/himall/src/main/java/cn/hiauth/himall/controller/IndexController.java
  class IndexController (line 27) | @Slf4j
    method index (line 40) | @GetMapping({"/", "/index"})
    method logout (line 45) | @GetMapping("/user/logout")
    method profile (line 55) | @GetMapping("/profile")

FILE: example/resource/src/main/java/cn/hiauth/resource/ResourceStarter.java
  class ResourceStarter (line 6) | @SpringBootApplication
    method main (line 9) | public static void main(String[] args) {

FILE: example/resource/src/main/java/cn/hiauth/resource/config/ResourceServerConfig.java
  class ResourceServerConfig (line 13) | @Configuration
    method securityFilterChain (line 18) | @Bean

FILE: example/resource/src/main/java/cn/hiauth/resource/config/auth/SimpleAccessDeniedHandler.java
  class SimpleAccessDeniedHandler (line 14) | public class SimpleAccessDeniedHandler implements AccessDeniedHandler {
    method handle (line 16) | @Override

FILE: example/resource/src/main/java/cn/hiauth/resource/config/auth/SimpleAuthenticationEntryPoint.java
  class SimpleAuthenticationEntryPoint (line 17) | public class SimpleAuthenticationEntryPoint implements AuthenticationEnt...
    method commence (line 19) | @Override

FILE: example/resource/src/main/java/cn/hiauth/resource/controller/IndexController.java
  class IndexController (line 6) | @RestController
    method index (line 9) | @GetMapping("/")

FILE: example/resource/src/main/java/cn/hiauth/resource/controller/ProfileController.java
  class ProfileController (line 9) | @PreAuthorize("hasAuthority('SCOPE_profile')")
    method info (line 14) | @GetMapping("/info")

FILE: example/resource/src/main/java/cn/hiauth/resource/controller/UnpapiController.java
  class UnpapiController (line 11) | @RestController
    method metadata (line 15) | @GetMapping("/metadata")

FILE: example/resource/src/main/java/cn/hiauth/resource/controller/UserController.java
  class UserController (line 9) | @PreAuthorize("hasAuthority('SCOPE_user')")
    method info (line 14) | @GetMapping("/info")

FILE: example/resource/src/main/java/cn/hiauth/resource/utils/ResponseTools.java
  class ResponseTools (line 10) | public class ResponseTools {
    method write (line 18) | public static void write(HttpServletResponse response, R<?> r) throws ...

FILE: example/spring-cloud-with-hiauth-client/gateway1/src/main/java/cn/hiauth/gateway/ApiController.java
  class ApiController (line 12) | @RestController
    method userinfo (line 16) | @ResponseBody

FILE: example/spring-cloud-with-hiauth-client/gateway1/src/main/java/cn/hiauth/gateway/GatewayStarter.java
  class GatewayStarter (line 8) | @SpringBootApplication
    method main (line 12) | public static void main(String[] args) {

FILE: example/spring-cloud-with-hiauth-client/gateway1/src/main/java/cn/hiauth/gateway/IndexController.java
  class IndexController (line 6) | @RestController
    method index (line 9) | @GetMapping("/")
    method home (line 14) | @GetMapping("/home")

FILE: example/spring-cloud-with-hiauth-client/ordersvc1/src/main/java/cn/hiauth/gateway/IndexController.java
  class IndexController (line 9) | @RestController
    method index (line 12) | @GetMapping("/api/info")

FILE: example/spring-cloud-with-hiauth-client/ordersvc1/src/main/java/cn/hiauth/gateway/OrderStarter.java
  class OrderStarter (line 9) | @EnableDiscoveryClient
    method main (line 14) | public static void main(String[] args) {

FILE: example/spring-cloud/gateway/src/main/java/cn/hiauth/gateway/ApiController.java
  class ApiController (line 9) | @RestController
    method userinfo (line 13) | @GetMapping("/userinfo")

FILE: example/spring-cloud/gateway/src/main/java/cn/hiauth/gateway/GatewayStarter.java
  class GatewayStarter (line 6) | @SpringBootApplication
    method main (line 9) | public static void main(String[] args) {

FILE: example/spring-cloud/gateway/src/main/java/cn/hiauth/gateway/IndexController.java
  class IndexController (line 6) | @RestController
    method index (line 9) | @GetMapping("/")
    method home (line 14) | @GetMapping("/home")

FILE: example/spring-cloud/gateway/src/main/java/cn/hiauth/gateway/SecurityConfig.java
  class SecurityConfig (line 16) | @Configuration
    method securityWebFilterChain (line 20) | @Bean
    method logoutSuccessHandler (line 39) | @Bean
    method logoutWebFilter (line 56) | @Bean

FILE: example/spring-cloud/ordersvc/src/main/java/cn/hiauth/gateway/IndexController.java
  class IndexController (line 7) | @RestController
    method index (line 10) | @GetMapping("/")

FILE: example/spring-cloud/ordersvc/src/main/java/cn/hiauth/gateway/OrderStarter.java
  class OrderStarter (line 7) | @EnableDiscoveryClient
    method main (line 11) | public static void main(String[] args) {

FILE: example/wechat-login/src/main/java/cn/hiauth/wechatlogin/WechatLoginStarter.java
  class WechatLoginStarter (line 6) | @SpringBootApplication
    method main (line 9) | public static void main(String[] args) {

FILE: example/wechat-login/src/main/java/cn/hiauth/wechatlogin/config/SecurityConfig.java
  class SecurityConfig (line 28) | @EnableWebSecurity
    method passwordEncoder (line 32) | @Bean
    method customUserDetailsService (line 37) | @Bean
    method restTemplate (line 42) | @Bean
    method webSecurityCustomizer (line 47) | @Bean
    method securityContextRepository (line 55) | @Bean
    method securityFilterChain (line 61) | @Bean
    method smsCodeAuthenticationFilter (line 86) | @Bean
    method qrCodeAuthenticationFilter (line 95) | @Bean
    method authenticationManager (line 103) | @Bean

FILE: example/wechat-login/src/main/java/cn/hiauth/wechatlogin/config/WebMvcConfig.java
  class WebMvcConfig (line 10) | @Configuration
    method addResourceHandlers (line 13) | @Override

FILE: example/wechat-login/src/main/java/cn/hiauth/wechatlogin/config/web/security/phone/SmsCodeAuthenticationFilter.java
  class SmsCodeAuthenticationFilter (line 12) | public class SmsCodeAuthenticationFilter extends AbstractAuthenticationP...
    method SmsCodeAuthenticationFilter (line 14) | public SmsCodeAuthenticationFilter() {
    method attemptAuthentication (line 18) | @Override

FILE: example/wechat-login/src/main/java/cn/hiauth/wechatlogin/config/web/security/phone/SmsCodeAuthenticationProvider.java
  class SmsCodeAuthenticationProvider (line 10) | public class SmsCodeAuthenticationProvider implements AuthenticationProv...
    method SmsCodeAuthenticationProvider (line 14) | public SmsCodeAuthenticationProvider(CustomUserDetailsService userDeta...
    method authenticate (line 18) | @Override
    method supports (line 40) | @Override

FILE: example/wechat-login/src/main/java/cn/hiauth/wechatlogin/config/web/security/phone/SmsCodeAuthenticationToken.java
  class SmsCodeAuthenticationToken (line 8) | public class SmsCodeAuthenticationToken extends AbstractAuthenticationTo...
    method SmsCodeAuthenticationToken (line 14) | public SmsCodeAuthenticationToken(String mobile, String code) {
    method SmsCodeAuthenticationToken (line 21) | public SmsCodeAuthenticationToken(Object principal, Collection<? exten...
    method getCredentials (line 27) | @Override
    method getPrincipal (line 32) | @Override

FILE: example/wechat-login/src/main/java/cn/hiauth/wechatlogin/config/web/security/wechat/QrCodeAuthenticationFilter.java
  class QrCodeAuthenticationFilter (line 10) | public class QrCodeAuthenticationFilter extends AbstractAuthenticationPr...
    method QrCodeAuthenticationFilter (line 12) | public QrCodeAuthenticationFilter() {
    method attemptAuthentication (line 16) | @Override

FILE: example/wechat-login/src/main/java/cn/hiauth/wechatlogin/config/web/security/wechat/QrCodeAuthenticationProvider.java
  class QrCodeAuthenticationProvider (line 10) | public class QrCodeAuthenticationProvider implements AuthenticationProvi...
    method QrCodeAuthenticationProvider (line 14) | public QrCodeAuthenticationProvider(CustomUserDetailsService userDetai...
    method authenticate (line 18) | @Override
    method supports (line 39) | @Override

FILE: example/wechat-login/src/main/java/cn/hiauth/wechatlogin/config/web/security/wechat/QrCodeAuthenticationToken.java
  class QrCodeAuthenticationToken (line 8) | public class QrCodeAuthenticationToken extends AbstractAuthenticationTok...
    method QrCodeAuthenticationToken (line 14) | public QrCodeAuthenticationToken(String code) {
    method QrCodeAuthenticationToken (line 21) | public QrCodeAuthenticationToken(Object principal, Collection<? extend...
    method getCredentials (line 27) | @Override
    method getPrincipal (line 32) | @Override

FILE: example/wechat-login/src/main/java/cn/hiauth/wechatlogin/controller/AuthController.java
  class AuthController (line 5) | @RestController

FILE: example/wechat-login/src/main/java/cn/hiauth/wechatlogin/controller/IndexController.java
  class IndexController (line 12) | @Slf4j
    method login (line 16) | @GetMapping("/login")
    method index (line 21) | @GetMapping({"/", "/index"})
    method home (line 28) | @GetMapping({"/home"})

FILE: example/wechat-login/src/main/java/cn/hiauth/wechatlogin/entity/CustomUserDetails.java
  class CustomUserDetails (line 8) | public class CustomUserDetails implements UserDetails {
    method CustomUserDetails (line 15) | public CustomUserDetails(String username, String password, boolean ena...
    method getAuthorities (line 23) | @Override
    method getPassword (line 28) | @Override
    method getUsername (line 33) | @Override
    method isAccountNonExpired (line 38) | @Override
    method isAccountNonLocked (line 43) | @Override
    method isCredentialsNonExpired (line 48) | @Override
    method isEnabled (line 53) | @Override

FILE: example/wechat-login/src/main/java/cn/hiauth/wechatlogin/service/CustomUserDetailsService.java
  class CustomUserDetailsService (line 11) | public class CustomUserDetailsService implements UserDetailsService {
    method CustomUserDetailsService (line 15) | public CustomUserDetailsService(PasswordEncoder passwordEncoder) {
    method loadUserByUsername (line 19) | @Override
    method loadUserByMobile (line 39) | public UserDetails loadUserByMobile(String mobile) throws UsernameNotF...
    method loadUserWeChatCode (line 51) | public UserDetails loadUserWeChatCode(String code) {

FILE: hiauth-client-starter/hiauth-client-commons/src/main/java/cn/hiauth/client/Authentication.java
  class Authentication (line 8) | @Data

FILE: hiauth-client-starter/hiauth-client-commons/src/main/java/cn/hiauth/client/Client.java
  class Client (line 5) | @Data

FILE: hiauth-client-starter/hiauth-client-commons/src/main/java/cn/hiauth/client/Constant.java
  class Constant (line 3) | public class Constant {

FILE: hiauth-client-starter/hiauth-client-commons/src/main/java/cn/hiauth/client/HiAuthToken.java
  class HiAuthToken (line 7) | @Data

FILE: hiauth-client-starter/hiauth-client-commons/src/main/java/cn/hiauth/client/JwtUtils.java
  class JwtUtils (line 11) | public class JwtUtils {
    method generateToken (line 24) | public static String generateToken(String sub, Integer expire) {
    method generateToken (line 43) | private static String generateToken(Map<String, Object> payload) {
    method parseToken (line 47) | public static JWT parseToken(String token) {

FILE: hiauth-client-starter/hiauth-client-commons/src/main/java/cn/hiauth/client/SecurityCorp.java
  class SecurityCorp (line 5) | @Data
    method SecurityCorp (line 11) | public SecurityCorp(Long id, String name) {

FILE: hiauth-client-starter/hiauth-client-commons/src/main/java/cn/hiauth/client/SecurityService.java
  type SecurityService (line 8) | public interface SecurityService {
    method loadSecurityUser (line 10) | SecurityUser loadSecurityUser(Authentication auth);
    method loadUserCorps (line 15) | List<SecurityCorp> loadUserCorps(Long userId);
    method switchCorp (line 20) | Boolean switchCorp(Long id);

FILE: hiauth-client-starter/hiauth-client-commons/src/main/java/cn/hiauth/client/SecurityUser.java
  class SecurityUser (line 5) | @Data

FILE: hiauth-client-starter/hiauth-client-commons/src/main/java/cn/hiauth/client/SessionContext.java
  class SessionContext (line 13) | @Data
    method SessionContext (line 26) | public SessionContext(String clientName, String cachePrefix, Integer c...

FILE: hiauth-client-starter/hiauth-client-commons/src/main/java/cn/hiauth/client/SessionContextHolder.java
  class SessionContextHolder (line 13) | public class SessionContextHolder {
    method setRedisTemplate (line 18) | public static void setRedisTemplate(RedisTemplate<String, String> redi...
    method getContext (line 22) | public static SessionContext getContext() {
    method setContext (line 26) | public static void setContext(SessionContext context) {
    method getAuthentication (line 30) | public static Authentication getAuthentication() {
    method getPrincipal (line 35) | public static SecurityUser getPrincipal() {
    method refresh (line 40) | public static void refresh() {
    method auth (line 49) | public static SessionContext auth(String clientName, String cachePrefi...
    method auth (line 55) | public static SessionContext auth(SessionContext context) {
    method auth (line 59) | public static SessionContext auth(SessionContext context, String cache...
    method logout (line 76) | public static void logout() {

FILE: hiauth-client-starter/hiauth-client-commons/src/main/java/cn/hiauth/client/TokenVo.java
  class TokenVo (line 3) | public class TokenVo {
    method TokenVo (line 11) | public TokenVo() {
    method TokenVo (line 14) | public TokenVo(String accessToken, String refreshToken, Integer expire...
    method getScope (line 21) | public String getScope() {
    method setScope (line 25) | public void setScope(String scope) {
    method getAccessToken (line 29) | public String getAccessToken() {
    method setAccessToken (line 33) | public void setAccessToken(String accessToken) {
    method getExpireIn (line 37) | public Integer getExpireIn() {
    method setExpireIn (line 41) | public void setExpireIn(Integer expireIn) {
    method getRefreshToken (line 45) | public String getRefreshToken() {
    method setRefreshToken (line 49) | public void setRefreshToken(String refreshToken) {

FILE: hiauth-client-starter/hiauth-client-commons/src/main/java/cn/hiauth/client/UserinfoVo.java
  class UserinfoVo (line 8) | @Data
    method toVo (line 22) | public static UserinfoVo toVo(Authentication auth) {

FILE: hiauth-client-starter/hiauth-client-resource-spring-boot-starter/src/main/java/cn/hiauth/client/resource/HiAuthClientResourceAutoConfig.java
  class HiAuthClientResourceAutoConfig (line 10) | @Slf4j

FILE: hiauth-client-starter/hiauth-client-resource-spring-boot-starter/src/main/java/cn/hiauth/client/resource/HiAuthClientResourceProperties.java
  class HiAuthClientResourceProperties (line 8) | @Data

FILE: hiauth-client-starter/hiauth-client-session-spring-boot-starter/src/main/java/cn/hiauth/client/session/AuthFilter.java
  class AuthFilter (line 27) | @Slf4j
    method AuthFilter (line 36) | public AuthFilter(HiAuthClientSessionProperties properties, RedisTempl...
    method init (line 41) | @Override
    method doFilter (line 46) | @Override
    method doIt (line 57) | private void doIt(HttpServletRequest request, HttpServletResponse resp...
    method getSessionContext (line 71) | private SessionContext getSessionContext(HttpServletRequest request) t...
    method matcherUrl (line 102) | public boolean matcherUrl(String uri) {
    method ignoreUrl (line 111) | public boolean ignoreUrl(String uri) {
    method printError (line 120) | private void printError(HttpServletRequest request, HttpServletRespons...
    method destroy (line 152) | @Override

FILE: hiauth-client-starter/hiauth-client-session-spring-boot-starter/src/main/java/cn/hiauth/client/session/HiAuthClientSessionAutoConfig.java
  class HiAuthClientSessionAutoConfig (line 16) | @Slf4j
    method authFilterRegister (line 27) | @Bean

FILE: hiauth-client-starter/hiauth-client-session-spring-boot-starter/src/main/java/cn/hiauth/client/session/HiAuthClientSessionCacheConfig.java
  class HiAuthClientSessionCacheConfig (line 19) | @Slf4j
    method redisTemplate (line 23) | @Bean

FILE: hiauth-client-starter/hiauth-client-session-spring-boot-starter/src/main/java/cn/hiauth/client/session/HiAuthClientSessionController.java
  class HiAuthClientSessionController (line 12) | @Slf4j
    method userInfo (line 20) | @ResponseBody
    method myCorps (line 27) | @ResponseBody
    method switchCorp (line 35) | @ResponseBody

FILE: hiauth-client-starter/hiauth-client-session-spring-boot-starter/src/main/java/cn/hiauth/client/session/HiAuthClientSessionProperties.java
  class HiAuthClientSessionProperties (line 9) | @Data

FILE: hiauth-client-starter/hiauth-client-session-spring-boot-starter/src/main/java/cn/hiauth/client/session/HiAuthClientSessionRunner.java
  class HiAuthClientSessionRunner (line 14) | @Slf4j
    method run (line 21) | @Override

FILE: hiauth-client-starter/hiauth-client-spring-boot-starter/src/main/java/cn/hiauth/client/AuthFilter.java
  class AuthFilter (line 26) | @Slf4j
    method AuthFilter (line 37) | public AuthFilter(HiAuthClientProperties properties, RedisTemplate<Str...
    method init (line 42) | @Override
    method doFilter (line 47) | @Override
    method doIt (line 58) | private void doIt(HttpServletRequest request, HttpServletResponse resp...
    method checkPermissions (line 82) | private void checkPermissions(HttpServletRequest request, List<Map<Str...
    method getSessionContext (line 104) | private SessionContext getSessionContext(HttpServletRequest request) t...
    method matcherUrl (line 135) | public boolean matcherUrl(String uri) {
    method ignoreUrl (line 144) | public boolean ignoreUrl(String uri) {
    method printError (line 153) | private void printError(HttpServletRequest request, HttpServletRespons...
    method destroy (line 185) | @Override

FILE: hiauth-client-starter/hiauth-client-spring-boot-starter/src/main/java/cn/hiauth/client/HiAuthCacheConfig.java
  class HiAuthCacheConfig (line 19) | @Slf4j
    method redisTemplate (line 23) | @Bean

FILE: hiauth-client-starter/hiauth-client-spring-boot-starter/src/main/java/cn/hiauth/client/HiAuthClientAutoConfig.java
  class HiAuthClientAutoConfig (line 17) | @Slf4j
    method restTemplate (line 28) | @Bean
    method authFilterRegister (line 34) | @Bean

FILE: hiauth-client-starter/hiauth-client-spring-boot-starter/src/main/java/cn/hiauth/client/HiAuthClientController.java
  class HiAuthClientController (line 29) | @Slf4j
    method login (line 49) | @GetMapping("/oauth2/login")
    method logout (line 59) | @GetMapping("/oauth2/logout")
    method getTokenJson (line 69) | @ResponseBody
    method getTokenHtml (line 81) | @GetMapping(value = "/oauth2/token/redirect")
    method auth (line 96) | private SessionContext auth(String code) throws HttpClientErrorExcepti...
    method userinfo (line 155) | @ResponseBody
    method updatePwd (line 162) | @ResponseBody
    method myCorps (line 170) | @ResponseBody
    method switchCorp (line 178) | @ResponseBody
    method getTokenByOauthServer (line 184) | private Map<?, ?> getTokenByOauthServer(String code) {
    method getUserInfoByOauthServer (line 197) | private Map<?, ?> getUserInfoByOauthServer(String accessToken) throws ...
    method updatePwdByOauthServer (line 206) | private Map<?, ?> updatePwdByOauthServer(String accessToken, String ra...

FILE: hiauth-client-starter/hiauth-client-spring-boot-starter/src/main/java/cn/hiauth/client/HiAuthClientProperties.java
  class HiAuthClientProperties (line 9) | @Data

FILE: hiauth-client-starter/hiauth-client-spring-boot-starter/src/main/java/cn/hiauth/client/HiAuthClientProviderProperties.java
  class HiAuthClientProviderProperties (line 8) | @Data

FILE: hiauth-client-starter/hiauth-client-spring-boot-starter/src/main/java/cn/hiauth/client/HiAuthClientRegistrationProperties.java
  class HiAuthClientRegistrationProperties (line 9) | @Data

FILE: hiauth-client-starter/hiauth-client-spring-boot-starter/src/main/java/cn/hiauth/client/HiAuthClientRunner.java
  class HiAuthClientRunner (line 13) | @Slf4j
    method run (line 20) | @Override

FILE: hiauth-client-starter/hiauth-client-spring-boot-starter/src/main/java/cn/hiauth/client/api/TokenVo.java
  class TokenVo (line 3) | public class TokenVo {
    method TokenVo (line 11) | public TokenVo() {
    method TokenVo (line 14) | public TokenVo(String accessToken, String refreshToken, Integer expire...
    method getScope (line 21) | public String getScope() {
    method setScope (line 25) | public void setScope(String scope) {
    method getAccessToken (line 29) | public String getAccessToken() {
    method setAccessToken (line 33) | public void setAccessToken(String accessToken) {
    method getExpireIn (line 37) | public Integer getExpireIn() {
    method setExpireIn (line 41) | public void setExpireIn(Integer expireIn) {
    method getRefreshToken (line 45) | public String getRefreshToken() {
    method setRefreshToken (line 49) | public void setRefreshToken(String refreshToken) {

FILE: hiauth-client-starter/hiauth-client-spring-boot-starter/src/main/java/cn/hiauth/client/api/UserPwdUpdateDto.java
  class UserPwdUpdateDto (line 5) | @Data

FILE: hiauth-client-starter/hiauth-client-spring-cloud-gateway-starter/src/main/java/cn/hiauth/client/gateway/AuthGatewayFilterFactory.java
  class AuthGatewayFilterFactory (line 29) | @Slf4j
    method AuthGatewayFilterFactory (line 36) | public AuthGatewayFilterFactory(HiAuthClientGatewayProperties hiAuthCl...
    method apply (line 42) | @Override
    method checkAuth (line 58) | private void checkAuth(ServerWebExchange exchange, String cachePrefix) {
    method matcherAuthUrl (line 72) | public boolean matcherAuthUrl(String uri) {
    method getSessionContext (line 81) | private SessionContext getSessionContext(ServerHttpRequest request, St...
    method handleException (line 105) | private Mono<Void> handleException(ServerWebExchange exchange, Throwab...
    method shortcutFieldOrder (line 125) | @Override
    class Config (line 130) | @Data

FILE: hiauth-client-starter/hiauth-client-spring-cloud-gateway-starter/src/main/java/cn/hiauth/client/gateway/HiAuthClientGatewayAutoConfig.java
  class HiAuthClientGatewayAutoConfig (line 25) | @Slf4j
    method authGatewayFilterFactory (line 33) | @Bean
    method restTemplate (line 38) | @Bean
    method redisTemplate (line 44) | @Bean

FILE: hiauth-client-starter/hiauth-client-spring-cloud-gateway-starter/src/main/java/cn/hiauth/client/gateway/HiAuthClientGatewayController.java
  class HiAuthClientGatewayController (line 29) | @Slf4j
    method login (line 43) | @GetMapping("/unpapi/{clientName}/oauth2/login")
    method getTokenHtml (line 57) | @GetMapping(value = "/unpapi/{clientName}/oauth2/token/redirect")
    method logout (line 78) | @GetMapping("/unpapi/{clientName}/oauth2/logout")
    method userinfo (line 89) | @ResponseBody
    method updatePwd (line 96) | @ResponseBody
    method auth (line 104) | private SessionContext auth(String clientName, Client client, String c...
    method getTokenByOauthServer (line 162) | private Map<?, ?> getTokenByOauthServer(Client client, String code) {
    method getUserInfoByOauthServer (line 175) | private Map<?, ?> getUserInfoByOauthServer(String accessToken) throws ...
    method updatePwdByOauthServer (line 184) | private Map<?, ?> updatePwdByOauthServer(String accessToken, String ra...

FILE: hiauth-client-starter/hiauth-client-spring-cloud-gateway-starter/src/main/java/cn/hiauth/client/gateway/HiAuthClientGatewayProperties.java
  class HiAuthClientGatewayProperties (line 11) | @Data

FILE: hiauth-client-starter/hiauth-client-spring-cloud-gateway-starter/src/main/java/cn/hiauth/client/gateway/HiAuthClientGatewayRunner.java
  class HiAuthClientGatewayRunner (line 14) | @Slf4j
    method run (line 21) | @Override

FILE: hiauth-client-starter/hiauth-client-spring-cloud-gateway-starter/src/main/java/cn/hiauth/client/gateway/UserPwdUpdateDto.java
  class UserPwdUpdateDto (line 5) | @Data

FILE: hiauth-front/apps/backend-mock/api/system/dept/list.ts
  function generateMockDataList (line 16) | function generateMockDataList(count: number) {

FILE: hiauth-front/apps/backend-mock/api/system/menu/name-exists.ts
  function getNames (line 8) | function getNames(menus: any[]) {

FILE: hiauth-front/apps/backend-mock/api/system/menu/path-exists.ts
  function getPaths (line 8) | function getPaths(menus: any[]) {

FILE: hiauth-front/apps/backend-mock/api/system/role/list.ts
  function generateMockDataList (line 19) | function generateMockDataList(count: number) {

FILE: hiauth-front/apps/backend-mock/api/table/list.ts
  function generateMockDataList (line 10) | function generateMockDataList(count: number) {
  type ItemType (line 75) | type ItemType = (typeof listData)[0];

FILE: hiauth-front/apps/backend-mock/utils/cookie-utils.ts
  function clearRefreshTokenCookie (line 5) | function clearRefreshTokenCookie(event: H3Event<EventHandlerRequest>) {
  function setRefreshTokenCookie (line 13) | function setRefreshTokenCookie(
  function getRefreshTokenFromCookie (line 25) | function getRefreshTokenFromCookie(event: H3Event<EventHandlerRequest>) {

FILE: hiauth-front/apps/backend-mock/utils/jwt-utils.ts
  constant ACCESS_TOKEN_SECRET (line 11) | const ACCESS_TOKEN_SECRET = 'access_token_secret';
  constant REFRESH_TOKEN_SECRET (line 12) | const REFRESH_TOKEN_SECRET = 'refresh_token_secret';
  type UserPayload (line 14) | interface UserPayload extends UserInfo {
  function generateAccessToken (line 19) | function generateAccessToken(user: UserInfo) {
  function generateRefreshToken (line 23) | function generateRefreshToken(user: UserInfo) {
  function verifyAccessToken (line 29) | function verifyAccessToken(
  function verifyRefreshToken (line 60) | function verifyRefreshToken(

FILE: hiauth-front/apps/backend-mock/utils/mock-data.ts
  type UserInfo (line 1) | interface UserInfo {
  constant MOCK_USERS (line 10) | const MOCK_USERS: UserInfo[] = [
  constant MOCK_CODES (line 36) | const MOCK_CODES = [
  constant MOCK_MENUS (line 174) | const MOCK_MENUS = [
  constant MOCK_MENU_LIST (line 189) | const MOCK_MENU_LIST = [
  function getMenuIds (line 381) | function getMenuIds(menus: any[]) {

FILE: hiauth-front/apps/backend-mock/utils/response.ts
  function useResponseSuccess (line 5) | function useResponseSuccess<T = any>(data: T) {
  function usePageResponseSuccess (line 14) | function usePageResponseSuccess<T = any>(
  function useResponseError (line 35) | function useResponseError(message: string, error: any = null) {
  function forbiddenResponse (line 44) | function forbiddenResponse(
  function unAuthorizedResponse (line 52) | function unAuthorizedResponse(event: H3Event<EventHandlerRequest>) {
  function sleep (line 57) | function sleep(ms: number) {
  function pagination (line 61) | function pagination<T = any>(

FILE: hiauth-front/apps/web-antd/src/adapter/component/index.ts
  type ComponentType (line 99) | type ComponentType =
  function initComponentAdapter (line 127) | async function initComponentAdapter() {

FILE: hiauth-front/apps/web-antd/src/adapter/form.ts
  function initSetupVbenForm (line 11) | async function initSetupVbenForm() {
  type VbenFormSchema (line 48) | type VbenFormSchema = FormSchema<ComponentType>;

FILE: hiauth-front/apps/web-antd/src/adapter/vxe-table.ts
  method renderTableDefault (line 43) | renderTableDefault(_renderOpts, params) {
  method renderTableDefault (line 51) | renderTableDefault(renderOpts) {

FILE: hiauth-front/apps/web-antd/src/api/core/auth.ts
  type LoginParams (line 5) | interface LoginParams {
  type LoginResult (line 11) | interface LoginResult {
  type RefreshTokenResult (line 15) | interface RefreshTokenResult {
  function loginApi (line 24) | async function loginApi(data: AuthApi.LoginParams) {
  function refreshTokenApi (line 31) | async function refreshTokenApi() {
  function logoutApi (line 40) | async function logoutApi() {
  function getAccessCodesApi (line 49) | async function getAccessCodesApi() {

FILE: hiauth-front/apps/web-antd/src/api/core/menu.ts
  function getAllMenusApi (line 8) | async function getAllMenusApi() {

FILE: hiauth-front/apps/web-antd/src/api/core/user.ts
  function getUserInfoApi (line 8) | async function getUserInfoApi() {

FILE: hiauth-front/apps/web-antd/src/api/request.ts
  function createRequestClient (line 24) | function createRequestClient(baseURL: string, options?: RequestClientOpt...

FILE: hiauth-front/apps/web-antd/src/bootstrap.ts
  function bootstrap (line 19) | async function bootstrap(namespace: string) {

FILE: hiauth-front/apps/web-antd/src/locales/index.ts
  function loadMessages (line 33) | async function loadMessages(lang: SupportedLanguagesType) {
  function loadThirdPartyMessage (line 45) | async function loadThirdPartyMessage(lang: SupportedLanguagesType) {
  function loadDayjsLocale (line 53) | async function loadDayjsLocale(lang: SupportedLanguagesType) {
  function loadAntdLocale (line 80) | async function loadAntdLocale(lang: SupportedLanguagesType) {
  function setupI18n (line 93) | async function setupI18n(app: App, options: LocaleSetupOptions = {}) {

FILE: hiauth-front/apps/web-antd/src/main.ts
  function initApplication (line 9) | async function initApplication() {

FILE: hiauth-front/apps/web-antd/src/router/access.ts
  function generateAccess (line 17) | async function generateAccess(options: GenerateMenuAndRoutesOptions) {

FILE: hiauth-front/apps/web-antd/src/router/guard.ts
  function setupCommonGuard (line 17) | function setupCommonGuard(router: Router) {
  function setupAccessGuard (line 47) | function setupAccessGuard(router: Router) {
  function createRouterGuard (line 126) | function createRouterGuard(router: Router) {

FILE: hiauth-front/apps/web-antd/src/store/auth.ts
  function authLogin (line 28) | async function authLogin(
  function logout (line 80) | async function logout(redirect: boolean = true) {
  function fetchUserInfo (line 100) | async function fetchUserInfo() {
  function $reset (line 107) | function $reset() {

FILE: hiauth-front/apps/web-auth/src/adapter/component/index.ts
  type ComponentType (line 99) | type ComponentType =
  function initComponentAdapter (line 127) | async function initComponentAdapter() {

FILE: hiauth-front/apps/web-auth/src/adapter/form.ts
  function initSetupVbenForm (line 11) | async function initSetupVbenForm() {
  type VbenFormSchema (line 48) | type VbenFormSchema = FormSchema<ComponentType>;

FILE: hiauth-front/apps/web-auth/src/adapter/vxe-table.ts
  method renderTableDefault (line 43) | renderTableDefault(_renderOpts, params) {
  method renderTableDefault (line 51) | renderTableDefault(renderOpts) {

FILE: hiauth-front/apps/web-auth/src/api/core/app.ts
  type AppPageDto (line 5) | interface AppPageDto extends PageDto {
  type AppLimitDto (line 9) | interface AppLimitDto extends LimitDto {
  type AppCreateDto (line 13) | interface AppCreateDto {
  type AppUpdateDto (line 19) | interface AppUpdateDto {
  type AppVo (line 26) | interface AppVo {

FILE: hiauth-front/apps/web-auth/src/api/core/appClient.ts
  type AppClientPageDto (line 6) | interface AppClientPageDto extends PageDto {
  type AppClientLimitDto (line 11) | interface AppClientLimitDto extends LimitDto {
  type AppClientCreateDto (line 16) | interface AppClientCreateDto {
  type AppClientUpdateDto (line 21) | interface AppClientUpdateDto {
  type AppClientDeleteDto (line 31) | interface AppClientDeleteDto {
  type AppClientVo (line 36) | interface AppClientVo {

FILE: hiauth-front/apps/web-auth/src/api/core/appResource.ts
  type AppResourcePageDto (line 5) | interface AppResourcePageDto extends PageDto {
  type AppResourceCreateDto (line 16) | interface AppResourceCreateDto {
  type AppResourceUpdateDto (line 28) | interface AppResourceUpdateDto {
  type FindAppResourceIdsByRoleAndAppDto (line 40) | interface FindAppResourceIdsByRoleAndAppDto {
  type AppResourceVo (line 45) | interface AppResourceVo {

FILE: hiauth-front/apps/web-auth/src/api/core/auth.ts
  type LoginParams (line 5) | interface LoginParams {
  type SmsCodeDto (line 10) | interface SmsCodeDto {
  type PhoneNumLoginDto (line 16) | interface PhoneNumLoginDto {
  type LoginResult (line 23) | interface LoginResult {
  type RefreshTokenResult (line 27) | interface RefreshTokenResult {
  type RegisterDto (line 33) | interface RegisterDto {
  function loginApi (line 44) | async function loginApi(data: AuthApi.LoginParams) {
  function phoneNumLoginApi (line 48) | async function phoneNumLoginApi(data: AuthApi.PhoneNumLoginDto) {
  function getSmsCodeApi (line 55) | async function getSmsCodeApi(data: AuthApi.SmsCodeDto) {
  function refreshTokenApi (line 62) | async function refreshTokenApi() {
  function logoutApi (line 71) | async function logoutApi() {
  function getAccessCodesApi (line 80) | async function getAccessCodesApi() {
  function registerApi (line 84) | async function registerApi(data: RegisterDto) {

FILE: hiauth-front/apps/web-auth/src/api/core/common.ts
  type R (line 3) | interface R<T = any> {
  type PageVo (line 9) | interface PageVo<T> {
  type PageDto (line 16) | interface PageDto {
  type LimitDto (line 21) | interface LimitDto {
  type FileUrlVo (line 26) | interface FileUrlVo {
  type MetadataVo (line 30) | interface MetadataVo {
  function getMetadataApi (line 61) | async function getMetadataApi() {
  function uploadImgApi (line 65) | async function uploadImgApi(file: File) {

FILE: hiauth-front/apps/web-auth/src/api/core/corp.ts
  type CorpPageDto (line 5) | interface CorpPageDto extends PageDto {
  type CorpLimitDto (line 9) | interface CorpLimitDto extends LimitDto {
  type CorpCreateDto (line 13) | interface CorpCreateDto {
  type CorpUpdateDto (line 18) | interface CorpUpdateDto {
  type CorpVo (line 24) | interface CorpVo {

FILE: hiauth-front/apps/web-auth/src/api/core/dep.ts
  type DepPageDto (line 5) | interface DepPageDto extends PageDto {
  type DepLimitDto (line 13) | interface DepLimitDto extends LimitDto {
  type DepCreateDto (line 18) | interface DepCreateDto {
  type DepUpdateDto (line 27) | interface DepUpdateDto {
  type DepVo (line 36) | interface DepVo {

FILE: hiauth-front/apps/web-auth/src/api/core/dict.ts
  type DictPageDto (line 5) | interface DictPageDto extends PageDto {
  type DictLimitDto (line 12) | interface DictLimitDto extends LimitDto {
  type DictCreateDto (line 17) | interface DictCreateDto {
  type DictUpdateDto (line 25) | interface DictUpdateDto {
  type DictVo (line 35) | interface DictVo {
  function pageDictApi (line 47) | async function pageDictApi(params: DictPageDto) {
  function getDictByIdApi (line 54) | async function getDictByIdApi(id: string) {
  function createDictApi (line 59) | async function createDictApi(params: DictCreateDto) {
  function updateDictApi (line 63) | async function updateDictApi(params: DictUpdateDto) {
  function deleteDictApi (line 67) | async function deleteDictApi(params: { ids: string[] }) {
  function findDictApi (line 71) | async function findDictApi(params: DictLimitDto) {
  function findSubDictApi (line 78) | async function findSubDictApi(params: DictLimitDto) {

FILE: hiauth-front/apps/web-auth/src/api/core/emp.ts
  type EmpPageDto (line 6) | interface EmpPageDto extends PageDto {
  type EmpCreateDto (line 13) | interface EmpCreateDto {
  type EmpUpdateDto (line 24) | interface EmpUpdateDto {
  type EmpVo (line 35) | interface EmpVo {

FILE: hiauth-front/apps/web-auth/src/api/core/menu.ts
  function getAllMenusApi (line 8) | async function getAllMenusApi() {

FILE: hiauth-front/apps/web-auth/src/api/core/role.ts
  type RolePageDto (line 5) | interface RolePageDto extends PageDto {
  type RoleLimitDto (line 10) | interface RoleLimitDto extends LimitDto {
  type RoleCreateDto (line 14) | interface RoleCreateDto {
  type RoleUpdateDto (line 21) | interface RoleUpdateDto {
  type RoleAuthDto (line 28) | interface RoleAuthDto {
  type RoleVo (line 34) | interface RoleVo {

FILE: hiauth-front/apps/web-auth/src/api/core/user.ts
  type UserPageDto (line 7) | interface UserPageDto extends PageDto {
  type UserLimitDto (line 18) | interface UserLimitDto extends LimitDto {
  type UserCreateDto (line 22) | interface UserCreateDto {
  type UserUpdateDto (line 32) | interface UserUpdateDto {
  type UserVo (line 43) | interface UserVo {
  function getUserInfoApi (line 69) | async function getUserInfoApi() {
  function pageUserApi (line 73) | async function pageUserApi(params: UserPageDto) {
  function getUserByIdApi (line 80) | async function getUserByIdApi(id: string) {
  function createUserApi (line 87) | async function createUserApi(params: UserCreateDto) {
  function updateUserApi (line 91) | async function updateUserApi(params: UserUpdateDto) {
  function deleteUsersApi (line 95) | async function deleteUsersApi(params: { ids: string[] }) {

FILE: hiauth-front/apps/web-auth/src/api/request.ts
  function createRequestClient (line 24) | function createRequestClient(baseURL: string, options?: RequestClientOpt...

FILE: hiauth-front/apps/web-auth/src/bootstrap.ts
  function bootstrap (line 19) | async function bootstrap(namespace: string) {

FILE: hiauth-front/apps/web-auth/src/common/constants.ts
  constant ROLE_SYS_ADMIN (line 1) | const ROLE_SYS_ADMIN = 'sysAdmin';
  constant ROLE_CORP_ADMIN (line 2) | const ROLE_CORP_ADMIN = 'corpAdmin';
  type ACTION (line 4) | enum ACTION {

FILE: hiauth-front/apps/web-auth/src/common/context.ts
  constant STORAGE_KEY (line 13) | const STORAGE_KEY = 'app-context';
  class ContextManager (line 15) | class ContextManager {
    method constructor (line 23) | constructor() {
    method getContext (line 31) | public getContext() {
    method resetContext (line 35) | resetContext() {
    method updateContext (line 47) | public updateContext(updates: DeepPartial<Context>) {
    method _saveContext (line 53) | private _saveContext(preference: Context) {
    method loadCachedContext (line 57) | private loadCachedContext() {
    method loadContext (line 61) | private loadContext(): Context {

FILE: hiauth-front/apps/web-auth/src/common/types.ts
  type AppContext (line 1) | interface AppContext {
  type Context (line 6) | interface Context {

FILE: hiauth-front/apps/web-auth/src/locales/index.ts
  function loadMessages (line 33) | async function loadMessages(lang: SupportedLanguagesType) {
  function loadThirdPartyMessage (line 45) | async function loadThirdPartyMessage(lang: SupportedLanguagesType) {
  function loadDayjsLocale (line 53) | async function loadDayjsLocale(lang: SupportedLanguagesType) {
  function loadAntdLocale (line 80) | async function loadAntdLocale(lang: SupportedLanguagesType) {
  function setupI18n (line 93) | async function setupI18n(app: App, options: LocaleSetupOptions = {}) {

FILE: hiauth-front/apps/web-auth/src/main.ts
  function initApplication (line 9) | async function initApplication() {

FILE: hiauth-front/apps/web-auth/src/router/access.ts
  function generateAccess (line 17) | async function generateAccess(options: GenerateMenuAndRoutesOptions) {

FILE: hiauth-front/apps/web-auth/src/router/guard.ts
  function setupCommonGuard (line 17) | function setupCommonGuard(router: Router) {
  function setupAccessGuard (line 47) | function setupAccessGuard(router: Router) {
  function createRouterGuard (line 126) | function createRouterGuard(router: Router) {

FILE: hiauth-front/apps/web-auth/src/store/auth.ts
  function authLogin (line 42) | async function authLogin(
  function smsCodeLogin (line 54) | async function smsCodeLogin(
  function changeSpace (line 66) | async function changeSpace(
  function logout (line 122) | async function logout(redirect: boolean = true) {
  function fetchUserInfo (line 142) | async function fetchUserInfo() {
  function $reset (line 149) | function $reset() {

FILE: hiauth-front/apps/web-auth/src/store/content.ts
  type ContentState (line 3) | interface ContentState {
  method setEncrypt (line 19) | setEncrypt(publicKey: string, encryptType: string) {

FILE: hiauth-front/apps/web-auth/src/utils/rsa.ts
  function encrypt (line 5) | function encrypt(publicKey: string, content: string) {

FILE: hiauth-front/apps/web-ele/src/adapter/component/index.ts
  type ComponentType (line 156) | type ComponentType =
  function initComponentAdapter (line 175) | async function initComponentAdapter() {

FILE: hiauth-front/apps/web-ele/src/adapter/form.ts
  function initSetupVbenForm (line 11) | async function initSetupVbenForm() {
  type VbenFormSchema (line 40) | type VbenFormSchema = FormSchema<ComponentType>;

FILE: hiauth-front/apps/web-ele/src/adapter/vxe-table.ts
  method renderTableDefault (line 43) | renderTableDefault(_renderOpts, params) {
  method renderTableDefault (line 52) | renderTableDefault(renderOpts) {

FILE: hiauth-front/apps/web-ele/src/api/core/auth.ts
  type LoginParams (line 5) | interface LoginParams {
  type LoginResult (line 11) | interface LoginResult {
  type RefreshTokenResult (line 15) | interface RefreshTokenResult {
  function loginApi (line 24) | async function loginApi(data: AuthApi.LoginParams) {
  function refreshTokenApi (line 31) | async function refreshTokenApi() {
  function logoutApi (line 40) | async function logoutApi() {
  function getAccessCodesApi (line 49) | async function getAccessCodesApi() {

FILE: hiauth-front/apps/web-ele/src/api/core/menu.ts
  function getAllMenusApi (line 8) | async function getAllMenusApi() {

FILE: hiauth-front/apps/web-ele/src/api/core/user.ts
  function getUserInfoApi (line 8) | async function getUserInfoApi() {

FILE: hiauth-front/apps/web-ele/src/api/request.ts
  function createRequestClient (line 24) | function createRequestClient(baseURL: string, options?: RequestClientOpt...

FILE: hiauth-front/apps/web-ele/src/bootstrap.ts
  function bootstrap (line 20) | async function bootstrap(namespace: string) {

FILE: hiauth-front/apps/web-ele/src/locales/index.ts
  function loadMessages (line 33) | async function loadMessages(lang: SupportedLanguagesType) {
  function loadThirdPartyMessage (line 45) | async function loadThirdPartyMessage(lang: SupportedLanguagesType) {
  function loadDayjsLocale (line 53) | async function loadDayjsLocale(lang: SupportedLanguagesType) {
  function loadElementLocale (line 80) | async function loadElementLocale(lang: SupportedLanguagesType) {
  function setupI18n (line 93) | async function setupI18n(app: App, options: LocaleSetupOptions = {}) {

FILE: hiauth-front/apps/web-ele/src/main.ts
  function initApplication (line 9) | async function initApplication() {

FILE: hiauth-front/apps/web-ele/src/router/access.ts
  function generateAccess (line 17) | async function generateAccess(options: GenerateMenuAndRoutesOptions) {

FILE: hiauth-front/apps/web-ele/src/router/guard.ts
  function setupCommonGuard (line 17) | function setupCommonGuard(router: Router) {
  function setupAccessGuard (line 47) | function setupAccessGuard(router: Router) {
  function createRouterGuard (line 126) | function createRouterGuard(router: Router) {

FILE: hiauth-front/apps/web-ele/src/store/auth.ts
  function authLogin (line 28) | async function authLogin(
  function logout (line 81) | async function logout(redirect: boolean = true) {
  function fetchUserInfo (line 101) | async function fetchUserInfo() {
  function $reset (line 108) | function $reset() {

FILE: hiauth-front/apps/web-naive/src/adapter/component/index.ts
  type ComponentType (line 102) | type ComponentType =
  function initComponentAdapter (line 121) | async function initComponentAdapter() {

FILE: hiauth-front/apps/web-naive/src/adapter/form.ts
  function initSetupVbenForm (line 11) | async function initSetupVbenForm() {
  type VbenFormSchema (line 44) | type VbenFormSchema = FormSchema<ComponentType>;

FILE: hiauth-front/apps/web-naive/src/adapter/vxe-table.ts
  method renderTableDefault (line 43) | renderTableDefault(_renderOpts, params) {
  method renderTableDefault (line 51) | renderTableDefault(renderOpts) {

FILE: hiauth-front/apps/web-naive/src/api/core/auth.ts
  type LoginParams (line 5) | interface LoginParams {
  type LoginResult (line 11) | interface LoginResult {
  type RefreshTokenResult (line 15) | interface RefreshTokenResult {
  function loginApi (line 24) | async function loginApi(data: AuthApi.LoginParams) {
  function refreshTokenApi (line 31) | async function refreshTokenApi() {
  function logoutApi (line 40) | async function logoutApi() {
  function getAccessCodesApi (line 49) | async function getAccessCodesApi() {

FILE: hiauth-front/apps/web-naive/src/api/core/menu.ts
  function getAllMenusApi (line 8) | async function getAllMenusApi() {

FILE: hiauth-front/apps/web-naive/src/api/core/user.ts
  function getUserInfoApi (line 8) | async function getUserInfoApi() {

FILE: hiauth-front/apps/web-naive/src/api/request.ts
  function createRequestClient (line 23) | function createRequestClient(baseURL: string, options?: RequestClientOpt...

FILE: hiauth-front/apps/web-naive/src/bootstrap.ts
  function bootstrap (line 19) | async function bootstrap(namespace: string) {

FILE: hiauth-front/apps/web-naive/src/locales/index.ts
  function loadMessages (line 24) | async function loadMessages(lang: SupportedLanguagesType) {
  function setupI18n (line 29) | async function setupI18n(app: App, options: LocaleSetupOptions = {}) {

FILE: hiauth-front/apps/web-naive/src/main.ts
  function initApplication (line 9) | async function initApplication() {

FILE: hiauth-front/apps/web-naive/src/router/access.ts
  function generateAccess (line 16) | async function generateAccess(options: GenerateMenuAndRoutesOptions) {

FILE: hiauth-front/apps/web-naive/src/router/guard.ts
  function setupCommonGuard (line 17) | function setupCommonGuard(router: Router) {
  function setupAccessGuard (line 47) | function setupAccessGuard(router: Router) {
  function createRouterGuard (line 125) | function createRouterGuard(router: Router) {

FILE: hiauth-front/apps/web-naive/src/store/auth.ts
  function authLogin (line 28) | async function authLogin(
  function logout (line 81) | async function logout(redirect: boolean = true) {
  function fetchUserInfo (line 101) | async function fetchUserInfo() {
  function $reset (line 108) | function $reset() {

FILE: hiauth-front/docs/.vitepress/config/plugins/demo-preview.ts
  function rawPathToToken (line 11) | function rawPathToToken(rawPath: string) {
  function generateContentHash (line 137) | function generateContentHash(input: string, length: number = 10): string {

FILE: hiauth-front/docs/.vitepress/theme/index.ts
  method enhanceApp (line 18) | async enhanceApp(ctx: EnhanceAppContext) {

FILE: hiauth-front/docs/.vitepress/theme/plugins/hm.ts
  constant SITE_ID (line 3) | const SITE_ID = '2e443a834727c065877c01d89921545e';
  type Window (line 6) | interface Window {
  function registerAnalytics (line 11) | function registerAnalytics() {
  function initHmPlugin (line 24) | function initHmPlugin() {

FILE: hiauth-front/docs/src/_env/adapter/component.ts
  type ComponentType (line 51) | type ComponentType =
  function initComponentAdapter (line 76) | async function initComponentAdapter() {

FILE: hiauth-front/docs/src/_env/adapter/form.ts
  type VbenFormSchema (line 46) | type VbenFormSchema = FormSchema<ComponentType>;

FILE: hiauth-front/docs/src/_env/adapter/vxe-table.ts
  method renderTableDefault (line 43) | renderTableDefault(_renderOpts, params) {
  method renderTableDefault (line 51) | renderTableDefault(renderOpts) {

FILE: hiauth-front/docs/src/_env/node/adapter/form.ts
  type VbenFormSchema (line 3) | type VbenFormSchema = any;
  type VbenFormProps (line 4) | type VbenFormProps = any;

FILE: hiauth-front/docs/src/demos/vben-vxe-table/mock-api.ts
  type PageFetchParams (line 4) | interface PageFetchParams {
  function sleep (line 11) | function sleep(time = 1000) {
  function getExampleTableApi (line 22) | async function getExampleTableApi(params: DemoTableApi.PageFetchParams) {

FILE: hiauth-front/docs/src/demos/vben-vxe-table/table-data.ts
  type TableRowData (line 1) | interface TableRowData {
  constant MOCK_TABLE_DATA (line 12) | const MOCK_TABLE_DATA: TableRowData[] = (() => {
  constant MOCK_TREE_TABLE_DATA (line 27) | const MOCK_TREE_TABLE_DATA = [
  constant MOCK_API_DATA (line 174) | const MOCK_API_DATA = [

FILE: hiauth-front/internal/lint-configs/eslint-config/src/configs/command.ts
  function command (line 3) | async function command() {

FILE: hiauth-front/internal/lint-configs/eslint-config/src/configs/comments.ts
  function comments (line 5) | async function comments(): Promise<Linter.Config[]> {

FILE: hiauth-front/internal/lint-configs/eslint-config/src/configs/disableds.ts
  function disableds (line 3) | async function disableds(): Promise<Linter.Config[]> {

FILE: hiauth-front/internal/lint-configs/eslint-config/src/configs/ignores.ts
  function ignores (line 3) | async function ignores(): Promise<Linter.Config[]> {

FILE: hiauth-front/internal/lint-configs/eslint-config/src/configs/import.ts
  function importPluginConfig (line 5) | async function importPluginConfig(): Promise<Linter.Config[]> {

FILE: hiauth-front/internal/lint-configs/eslint-config/src/configs/javascript.ts
  function javascript (line 7) | async function javascript(): Promise<Linter.Config[]> {

FILE: hiauth-front/internal/lint-configs/eslint-config/src/configs/jsdoc.ts
  function jsdoc (line 5) | async function jsdoc(): Promise<Linter.Config[]> {

FILE: hiauth-front/internal/lint-configs/eslint-config/src/configs/jsonc.ts
  function jsonc (line 5) | async function jsonc(): Promise<Linter.Config[]> {
  function sortPackageJson (line 54) | function sortPackageJson(): Linter.Config {
  function sortTsconfig (line 133) | function sortTsconfig(): Linter.Config {

FILE: hiauth-front/internal/lint-configs/eslint-config/src/configs/node.ts
  function node (line 5) | async function node(): Promise<Linter.Config[]> {

FILE: hiauth-front/internal/lint-configs/eslint-config/src/configs/perfectionist.ts
  function perfectionist (line 5) | async function perfectionist(): Promise<Linter.Config[]> {

FILE: hiauth-front/internal/lint-configs/eslint-config/src/configs/prettier.ts
  function prettier (line 5) | async function prettier(): Promise<Linter.Config[]> {

FILE: hiauth-front/internal/lint-configs/eslint-config/src/configs/regexp.ts
  function regexp (line 5) | async function regexp(): Promise<Linter.Config[]> {

FILE: hiauth-front/internal/lint-configs/eslint-config/src/configs/test.ts
  function test (line 5) | async function test(): Promise<Linter.Config[]> {

FILE: hiauth-front/internal/lint-configs/eslint-config/src/configs/turbo.ts
  function turbo (line 5) | async function turbo(): Promise<Linter.Config[]> {

FILE: hiauth-front/internal/lint-configs/eslint-config/src/configs/typescript.ts
  function typescript (line 5) | async function typescript(): Promise<Linter.Config[]> {

FILE: hiauth-front/internal/lint-configs/eslint-config/src/configs/unicorn.ts
  function unicorn (line 5) | async function unicorn(): Promise<Linter.Config[]> {

FILE: hiauth-front/internal/lint-configs/eslint-config/src/configs/vue.ts
  function vue (line 5) | async function vue(): Promise<Linter.Config[]> {

FILE: hiauth-front/internal/lint-configs/eslint-config/src/index.ts
  type FlatConfig (line 24) | type FlatConfig = Linter.Config;
  type FlatConfigPromise (line 26) | type FlatConfigPromise =
  function defineConfig (line 32) | async function defineConfig(config: FlatConfig[] = []) {

FILE: hiauth-front/internal/lint-configs/eslint-config/src/util.ts
  type Awaitable (line 1) | type Awaitable<T> = Promise<T> | T;
  function interopDefault (line 3) | async function interopDefault<T>(

FILE: hiauth-front/internal/node-utils/src/constants.ts
  type UNICODE (line 1) | enum UNICODE {

FILE: hiauth-front/internal/node-utils/src/fs.ts
  function outputJSON (line 4) | async function outputJSON(
  function ensureFile (line 20) | async function ensureFile(filePath: string) {
  function readJSON (line 31) | async function readJSON(filePath: string) {

FILE: hiauth-front/internal/node-utils/src/git.ts
  function getStagedFiles (line 10) | async function getStagedFiles(): Promise<string[]> {

FILE: hiauth-front/internal/node-utils/src/hash.ts
  function generatorContentHash (line 8) | function generatorContentHash(content: string, hashLSize?: number) {

FILE: hiauth-front/internal/node-utils/src/monorepo.ts
  function findMonorepoRoot (line 13) | function findMonorepoRoot(cwd: string = process.cwd()) {
  function getPackagesSync (line 24) | function getPackagesSync() {
  function getPackages (line 32) | async function getPackages() {
  function getPackage (line 41) | async function getPackage(pkgName: string) {

FILE: hiauth-front/internal/node-utils/src/path.ts
  function toPosixPath (line 7) | function toPosixPath(pathname: string) {

FILE: hiauth-front/internal/node-utils/src/prettier.ts
  function prettierFormat (line 5) | async function prettierFormat(filepath: string) {

FILE: hiauth-front/internal/node-utils/src/spinner.ts
  type SpinnerOptions (line 5) | interface SpinnerOptions {
  function spinner (line 10) | async function spinner<T>(

FILE: hiauth-front/internal/tailwind-config/src/index.ts
  function createColorsPalette (line 207) | function createColorsPalette(name: string) {

FILE: hiauth-front/internal/vite-config/src/config/application.ts
  function defineApplicationConfig (line 17) | function defineApplicationConfig(userConfigPromise?: DefineApplicationOp...
  function createCssOptions (line 103) | function createCssOptions(injectGlobalScss = true): CSSOptions {

FILE: hiauth-front/internal/vite-config/src/config/common.ts
  function getCommonConfig (line 3) | async function getCommonConfig(): Promise<UserConfig> {

FILE: hiauth-front/internal/vite-config/src/config/index.ts
  function defineConfig (line 12) | function defineConfig(

FILE: hiauth-front/internal/vite-config/src/config/library.ts
  function defineLibraryConfig (line 12) | function defineLibraryConfig(userConfigPromise?: DefineLibraryOptions) {

FILE: hiauth-front/internal/vite-config/src/plugins/archiver.ts
  method handler (line 17) | handler() {
  function zipFolder (line 46) | async function zipFolder(

FILE: hiauth-front/internal/vite-config/src/plugins/extra-app-config.ts
  type PluginOptions (line 11) | interface PluginOptions {
  constant GLOBAL_CONFIG_FILE_NAME (line 16) | const GLOBAL_CONFIG_FILE_NAME = '_app.config.js';
  constant VBEN_ADMIN_PRO_APP_CONF (line 17) | const VBEN_ADMIN_PRO_APP_CONF = '_VBEN_ADMIN_PRO_APP_CONF_';
  function viteExtraAppConfigPlugin (line 24) | async function viteExtraAppConfigPlugin({
  function getConfigSource (line 73) | async function getConfigSource() {
  function ensureTrailingSlash (line 88) | function ensureTrailingSlash(path: string) {

FILE: hiauth-front/internal/vite-config/src/plugins/importmap.ts
  constant DEFAULT_PROVIDER (line 11) | const DEFAULT_PROVIDER = 'jspm.io';
  type pluginOptions (line 13) | type pluginOptions = GeneratorOptions & {
  function getShimsUrl (line 25) | async function getShimsUrl(provide: string) {
  function viteImportMapPlugin (line 44) | async function viteImportMapPlugin(
  function injectShimsToHtml (line 194) | async function injectShimsToHtml(html: string, esModuleShimUrl: string) {

FILE: hiauth-front/internal/vite-config/src/plugins/index.ts
  function loadConditionPlugins (line 34) | async function loadConditionPlugins(conditionPlugins: ConditionPlugin[]) {
  function loadCommonPlugins (line 48) | async function loadCommonPlugins(
  function loadApplicationPlugins (line 88) | async function loadApplicationPlugins(
  function loadLibraryPlugins (line 222) | async function loadLibraryPlugins(

FILE: hiauth-front/internal/vite-config/src/plugins/inject-app-loading/index.ts
  function viteInjectAppLoadingPlugin (line 14) | async function viteInjectAppLoadingPlugin(
  function getLoadingRawByHtmlTemplate (line 54) | async function getLoadingRawByHtmlTemplate(loadingTemplate: string) {

FILE: hiauth-front/internal/vite-config/src/plugins/inject-metadata.ts
  function resolvePackageVersion (line 12) | function resolvePackageVersion(
  function resolveMonorepoDependencies (line 29) | async function resolveMonorepoDependencies() {
  function viteMetadataPlugin (line 70) | async function viteMetadataPlugin(

FILE: hiauth-front/internal/vite-config/src/plugins/license.ts
  function viteLicensePlugin (line 17) | async function viteLicensePlugin(

FILE: hiauth-front/internal/vite-config/src/plugins/nitro-mock.ts
  method configureServer (line 18) | async configureServer(server) {
  function runNitroServer (line 48) | async function runNitroServer(rootDir: string, port: number, verbose: bo...

FILE: hiauth-front/internal/vite-config/src/plugins/print.ts
  method configureServer (line 13) | configureServer(server) {

FILE: hiauth-front/internal/vite-config/src/plugins/vxe-table.ts
  function viteVxeTableImportsPlugin (line 5) | async function viteVxeTableImportsPlugin(): Promise<PluginOption> {

FILE: hiauth-front/internal/vite-config/src/typing.ts
  type IImportMap (line 23) | interface IImportMap {
  type PrintPluginOptions (line 36) | interface PrintPluginOptions {
  type NitroMockPluginOptions (line 55) | interface NitroMockPluginOptions {
  type ArchiverPluginOptions (line 79) | interface ArchiverPluginOptions {
  type ImportmapPluginOptions (line 96) | interface ImportmapPluginOptions {
  type ConditionPlugin (line 126) | interface ConditionPlugin {
  type CommonPluginOptions (line 143) | interface CommonPluginOptions {
  type ApplicationPluginOptions (line 181) | interface ApplicationPluginOptions extends CommonPluginOptions {
  type LibraryPluginOptions (line 283) | interface LibraryPluginOptions extends CommonPluginOptions {
  type ApplicationOptions (line 295) | type ApplicationOptions = ApplicationPluginOptions;
  type LibraryOptions (line 300) | type LibraryOptions = LibraryPluginOptions;
  type DefineApplicationOptions (line 306) | type DefineApplicationOptions = (config?: ConfigEnv) => Promise<{
  type DefineLibraryOptions (line 317) | type DefineLibraryOptions = (config?: ConfigEnv) => Promise<{
  type DefineConfig (line 328) | type DefineConfig = DefineApplicationOptions | DefineLibraryOptions;

FILE: hiauth-front/internal/vite-config/src/utils/env.ts
  function getConfFiles (line 21) | function getConfFiles() {
  function loadEnv (line 37) | async function loadEnv<T = Record<string, string>>(
  function loadAndConvertEnv (line 66) | async function loadAndConvertEnv(

FILE: hiauth-front/packages/@core/base/icons/src/create-icon.ts
  function createIconifyIcon (line 5) | function createIconifyIcon(icon: string) {

FILE: hiauth-front/packages/@core/base/shared/src/cache/storage-manager.ts
  type StorageType (line 1) | type StorageType = 'localStorage' | 'sessionStorage';
  type StorageManagerOptions (line 3) | interface StorageManagerOptions {
  type StorageItem (line 8) | interface StorageItem<T> {
  class StorageManager (line 13) | class StorageManager {
    method constructor (line 17) | constructor({
    method clear (line 31) | clear(): void {
    method clearExpiredItems (line 45) | clearExpiredItems(): void {
    method getItem (line 61) | getItem<T>(key: string, defaultValue: null | T = null): null | T {
    method removeItem (line 86) | removeItem(key: string): void {
    method setItem (line 97) | setItem<T>(key: string, value: T, ttl?: number): void {
    method getFullKey (line 113) | private getFullKey(key: string): string {

FILE: hiauth-front/packages/@core/base/shared/src/cache/types.ts
  type StorageType (line 1) | type StorageType = 'localStorage' | 'sessionStorage';
  type StorageValue (line 3) | interface StorageValue<T> {
  type IStorageCache (line 8) | interface IStorageCache {

FILE: hiauth-front/packages/@core/base/shared/src/color/color.ts
  function isDarkColor (line 3) | function isDarkColor(color: string) {
  function isLightColor (line 7) | function isLightColor(color: string) {

FILE: hiauth-front/packages/@core/base/shared/src/color/convert.ts
  function convertToHsl (line 11) | function convertToHsl(color: string): string {
  function convertToHslCssVar (line 26) | function convertToHslCssVar(color: string): string {
  function convertToRgb (line 40) | function convertToRgb(str: string): string {
  function isValidColor (line 49) | function isValidColor(color?: string) {

FILE: hiauth-front/packages/@core/base/shared/src/color/generator.ts
  type ColorItem (line 5) | interface ColorItem {
  function generatorColorVariables (line 11) | function generatorColorVariables(colorItems: ColorItem[]) {

FILE: hiauth-front/packages/@core/base/shared/src/constants/globals.ts
  constant CSS_VARIABLE_LAYOUT_CONTENT_HEIGHT (line 2) | const CSS_VARIABLE_LAYOUT_CONTENT_HEIGHT = `--vben-content-height`;
  constant CSS_VARIABLE_LAYOUT_CONTENT_WIDTH (line 4) | const CSS_VARIABLE_LAYOUT_CONTENT_WIDTH = `--vben-content-width`;
  constant CSS_VARIABLE_LAYOUT_HEADER_HEIGHT (line 6) | const CSS_VARIABLE_LAYOUT_HEADER_HEIGHT = `--vben-header-height`;
  constant CSS_VARIABLE_LAYOUT_FOOTER_HEIGHT (line 8) | const CSS_VARIABLE_LAYOUT_FOOTER_HEIGHT = `--vben-footer-height`;
  constant ELEMENT_ID_MAIN_CONTENT (line 11) | const ELEMENT_ID_MAIN_CONTENT = `__vben_main_content`;
  constant DEFAULT_NAMESPACE (line 16) | const DEFAULT_NAMESPACE = 'vben';

FILE: hiauth-front/packages/@core/base/shared/src/constants/vben.ts
  constant VBEN_GITHUB_URL (line 4) | const VBEN_GITHUB_URL = 'https://github.com/vbenjs/vue-vben-admin';
  constant VBEN_DOC_URL (line 9) | const VBEN_DOC_URL = 'https://doc.vben.pro';
  constant VBEN_LOGO_URL (line 14) | const VBEN_LOGO_URL =
  constant VBEN_PREVIEW_URL (line 20) | const VBEN_PREVIEW_URL = 'https://www.vben.pro';
  constant VBEN_ELE_PREVIEW_URL (line 22) | const VBEN_ELE_PREVIEW_URL = 'https://ele.vben.pro';
  constant VBEN_NAIVE_PREVIEW_URL (line 24) | const VBEN_NAIVE_PREVIEW_URL = 'https://naive.vben.pro';
  constant VBEN_ANT_PREVIEW_URL (line 26) | const VBEN_ANT_PREVIEW_URL = 'https://ant.vben.pro';

FILE: hiauth-front/packages/@core/base/shared/src/global-state.ts
  type ComponentsState (line 6) | interface ComponentsState {
  type MessageState (line 10) | interface MessageState {
  type IGlobalSharedState (line 14) | interface IGlobalSharedState {
  class GlobalShareState (line 19) | class GlobalShareState {
    method defineMessage (line 26) | public defineMessage({ copyPreferencesSuccess }: MessageState) {
    method getComponents (line 32) | public getComponents(): ComponentsState {
    method getMessage (line 36) | public getMessage(): MessageState {
    method setComponents (line 40) | public setComponents(value: ComponentsState) {

FILE: hiauth-front/packages/@core/base/shared/src/utils/__tests__/tree.test.ts
  type Node (line 6) | interface Node {
  type NodeValue (line 11) | type NodeValue = string;

FILE: hiauth-front/packages/@core/base/shared/src/utils/__tests__/util.test.ts
  class TestClass (line 5) | class TestClass {
    method constructor (line 8) | constructor(value: string) {
    method getValue (line 13) | getValue() {
    method setValue (line 17) | setValue(newValue: string) {
  class TestWithGetterSetter (line 58) | class TestWithGetterSetter {
    method value (line 59) | get value() {
    method value (line 63) | set value(newValue: string) {
    method constructor (line 69) | constructor() {
  type UserProfile (line 83) | interface UserProfile {
  type UserSettings (line 88) | interface UserSettings {
  type Data (line 92) | interface Data {

FILE: hiauth-front/packages/@core/base/shared/src/utils/cn.ts
  function cn (line 6) | function cn(...inputs: ClassValue[]) {

FILE: hiauth-front/packages/@core/base/shared/src/utils/date.ts
  function formatDate (line 3) | function formatDate(time: number | string, format = 'YYYY-MM-DD') {
  function formatDateTime (line 16) | function formatDateTime(time: number | string) {
  function isDate (line 20) | function isDate(value: any): value is Date {
  function isDayjsObject (line 24) | function isDayjsObject(value: any): value is dayjs.Dayjs {

FILE: hiauth-front/packages/@core/base/shared/src/utils/diff.ts
  function arraysEqual (line 5) | function arraysEqual<T>(a: T[], b: T[]): boolean {
  type DiffResult (line 58) | type DiffResult<T> = Partial<{
  function diff (line 62) | function diff<T extends Record<string, any>>(obj1: T, obj2: T): DiffResu...

FILE: hiauth-front/packages/@core/base/shared/src/utils/dom.ts
  type VisibleDomRect (line 1) | interface VisibleDomRect {
  function getElementVisibleRect (line 14) | function getElementVisibleRect(
  function getScrollbarWidth (line 54) | function getScrollbarWidth() {
  function needsScrollbar (line 73) | function needsScrollbar() {
  function triggerWindowResize (line 89) | function triggerWindowResize(): void {

FILE: hiauth-front/packages/@core/base/shared/src/utils/download.ts
  type DownloadOptions (line 3) | interface DownloadOptions<T = string> {
  constant DEFAULT_FILENAME (line 9) | const DEFAULT_FILENAME = 'downloaded_file';
  function downloadFileFromUrl (line 15) | async function downloadFileFromUrl({
  function downloadFileFromBase64 (line 46) | function downloadFileFromBase64({ fileName, source }: DownloadOptions) {
  function downloadFileFromImageUrl (line 58) | async function downloadFileFromImageUrl({
  function downloadFileFromBlob (line 69) | function downloadFileFromBlob({
  function downloadFileFromBlobPart (line 84) | function downloadFileFromBlobPart({
  function urlToBase64 (line 103) | function urlToBase64(url: string, mineType?: string): Promise<string> {
  function triggerDownload (line 130) | function triggerDownload(
  function resolveFileName (line 155) | function resolveFileName(url: string, fileName?: string): string {

FILE: hiauth-front/packages/@core/base/shared/src/utils/inference.ts
  function isUndefined (line 10) | function isUndefined(value?: unknown): value is undefined {
  function isBoolean (line 19) | function isBoolean(value: unknown): value is boolean {
  function isEmpty (line 37) | function isEmpty<T = unknown>(value?: T): value is T {
  function isHttpUrl (line 63) | function isHttpUrl(url?: string): boolean {
  function isWindow (line 78) | function isWindow(value: any): value is Window {
  function isMacOs (line 92) | function isMacOs(): boolean {
  function isWindowsOs (line 105) | function isWindowsOs(): boolean {
  function isNumber (line 114) | function isNumber(value: any): value is number {
  function getFirstNonNullOrUndefined (line 141) | function getFirstNonNullOrUndefined<T>(

FILE: hiauth-front/packages/@core/base/shared/src/utils/letter.ts
  function capitalizeFirstLetter (line 5) | function capitalizeFirstLetter(string: string): string {
  function toLowerCaseFirstLetter (line 15) | function toLowerCaseFirstLetter(str: string): string {
  function toCamelCase (line 25) | function toCamelCase(key: string, parentKey: string): string {
  function kebabToCamelCase (line 32) | function kebabToCamelCase(str: string): string {

FILE: hiauth-front/packages/@core/base/shared/src/utils/nprogress.ts
  function loadNprogress (line 13) | async function loadNprogress() {
  function startProgress (line 29) | async function startProgress() {
  function stopProgress (line 38) | async function stopProgress() {

FILE: hiauth-front/packages/@core/base/shared/src/utils/resources.ts
  function loadScript (line 5) | function loadScript(src: string) {

FILE: hiauth-front/packages/@core/base/shared/src/utils/state-handler.ts
  class StateHandler (line 1) | class StateHandler {
    method isConditionTrue (line 6) | isConditionTrue(): boolean {
    method reset (line 10) | reset() {
    method setConditionFalse (line 16) | setConditionFalse() {
    method setConditionTrue (line 25) | setConditionTrue() {
    method waitForCondition (line 34) | waitForCondition(): Promise<void> {
    method clearPromises (line 46) | private clearPromises() {

FILE: hiauth-front/packages/@core/base/shared/src/utils/to.ts
  function to (line 6) | async function to<T, U = Error>(

FILE: hiauth-front/packages/@core/base/shared/src/utils/tree.ts
  type TreeConfigOptions (line 1) | interface TreeConfigOptions {
  function traverseTreeValues (line 13) | function traverseTreeValues<T, V>(
  function filterTree (line 50) | function filterTree<T extends Record<string, any>>(
  function mapTree (line 80) | function mapTree<T, V extends Record<string, any>>(

FILE: hiauth-front/packages/@core/base/shared/src/utils/unique.ts
  function uniqueByField (line 7) | function uniqueByField<T>(arr: T[], key: keyof T): T[] {

FILE: hiauth-front/packages/@core/base/shared/src/utils/update-css-variables.ts
  function updateCSSVariables (line 5) | function updateCSSVariables(

FILE: hiauth-front/packages/@core/base/shared/src/utils/util.ts
  function bindMethods (line 1) | function bindMethods<T extends object>(instance: T): void {
  function getNestedValue (line 27) | function getNestedValue<T>(obj: T, path: string): any {

FILE: hiauth-front/packages/@core/base/shared/src/utils/window.ts
  type OpenWindowOptions (line 1) | interface OpenWindowOptions {
  function openWindow (line 13) | function openWindow(url: string, options: OpenWindowOptions = {}): void {
  function openRouteInNewWindow (line 30) | function openRouteInNewWindow(path: string) {

FILE: hiauth-front/packages/@core/base/typings/src/app.d.ts
  type LayoutType (line 1) | type LayoutType =
  type ThemeModeType (line 10) | type ThemeModeType = 'auto' | 'dark' | 'light';
  type PreferencesButtonPositionType (line 18) | type PreferencesButtonPositionType = 'auto' | 'fixed' | 'header';
  type BuiltinThemeType (line 20) | type BuiltinThemeType =
  type ContentCompactType (line 40) | type ContentCompactType = 'compact' | 'wide';
  type LayoutHeaderModeType (line 42) | type LayoutHeaderModeType = 'auto' | 'auto-scroll' | 'fixed' | 'static';
  type LayoutHeaderMenuAlignType (line 43) | type LayoutHeaderMenuAlignType = 'center' | 'end' | 'start';
  type LoginExpiredModeType (line 50) | type LoginExpiredModeType = 'modal' | 'page';
  type BreadcrumbStyleType (line 57) | type BreadcrumbStyleType = 'background' | 'normal';
  type AccessModeType (line 65) | type AccessModeType = 'backend' | 'frontend' | 'mixed';
  type NavigationStyleType (line 72) | type NavigationStyleType = 'plain' | 'rounded';
  type TabsStyleType (line 81) | type TabsStyleType = 'brisk' | 'card' | 'chrome' | 'plain';
  type PageTransitionType (line 86) | type PageTransitionType = 'fade' | 'fade-down' | 'fade-slide' | 'fade-up';
  type AuthPageLayoutType (line 94) | type AuthPageLayoutType = 'panel-center' | 'panel-left' | 'panel-right';

FILE: hiauth-front/packages/@core/base/typings/src/basic.d.ts
  type BasicOption (line 1) | interface BasicOption {
  type SelectOption (line 6) | type SelectOption = BasicOption;
  type TabOption (line 8) | type TabOption = BasicOption;
  type BasicUserInfo (line 10) | interface BasicUserInfo {
  type ClassType (line 33) | type ClassType = Array<object | string> | object | string;

FILE: hiauth-front/packages/@core/base/typings/src/helper.d.ts
  type DeepPartial (line 6) | type DeepPartial<T> = T extends object
  type DeepReadonly (line 15) | type DeepReadonly<T> = {
  type AnyPromiseFunction (line 23) | type AnyPromiseFunction<T extends any[] = any[], R = void> = (
  type AnyNormalFunction (line 30) | type AnyNormalFunction<T extends any[] = any[], R = void> = (...arg: T) ...
  type AnyFunction (line 35) | type AnyFunction<T extends any[] = any[], R = void> =
  type Nullable (line 42) | type Nullable<T> = null | T;
  type NonNullable (line 47) | type NonNullable<T> = T extends null | undefined ? never : T;
  type Recordable (line 52) | type Recordable<T> = Record<string, T>;
  type ReadonlyRecordable (line 57) | interface ReadonlyRecordable<T = any> {
  type TimeoutHandle (line 64) | type TimeoutHandle = ReturnType<typeof setTimeout>;
  type IntervalHandle (line 69) | type IntervalHandle = ReturnType<typeof setInterval>;
  type MaybeReadonlyRef (line 75) | type MaybeReadonlyRef<T> = (() => T) | ComputedRef<T>;
  type MaybeComputedRef (line 81) | type MaybeComputedRef<T> = MaybeReadonlyRef<T> | MaybeRef<T>;
  type Merge (line 83) | type Merge<O extends object, T extends object> = {
  type MergeAll (line 103) | type MergeAll<
  type EmitType (line 110) | type EmitType = (name: Name, ...args: any[]) => void;
  type MaybePromise (line 112) | type MaybePromise<T> = Promise<T> | T;

FILE: hiauth-front/packages/@core/base/typings/src/menu-record.ts
  type ExRouteRecordRaw (line 7) | type ExRouteRecordRaw = RouteRecordRaw & {
  type MenuRecordBadgeRaw (line 13) | interface MenuRecordBadgeRaw {
  type MenuRecordRaw (line 31) | interface MenuRecordRaw extends MenuRecordBadgeRaw {

FILE: hiauth-front/packages/@core/base/typings/src/tabs.ts
  type TabDefinition (line 3) | interface TabDefinition extends RouteLocationNormalized {

FILE: hiauth-front/packages/@core/base/typings/src/vue-router.d.ts
  type RouteMeta (line 4) | interface RouteMeta {
  type RouteRecordStringComponent (line 127) | type RouteRecordStringComponent<T = string> = Omit<
  type ComponentRecordType (line 135) | type ComponentRecordType = Record<string, () => Promise<Component>>;
  type GenerateMenuAndRoutesOptions (line 137) | interface GenerateMenuAndRoutesOptions {

FILE: hiauth-front/packages/@core/base/typings/vue-router.d.ts
  type RouteMeta (line 8) | interface RouteMeta extends IRouteMeta {}

FILE: hiauth-front/packages/@core/composables/src/use-is-mobile.ts
  function useIsMobile (line 3) | function useIsMobile() {

FILE: hiauth-front/packages/@core/composables/src/use-layout-style.ts
  function useLayoutContentStyle (line 20) | function useLayoutContentStyle() {
  function useLayoutHeaderStyle (line 63) | function useLayoutHeaderStyle() {
  function useLayoutFooterStyle (line 76) | function useLayoutFooterStyle() {

FILE: hiauth-front/packages/@core/composables/src/use-namespace.ts
  type UseNamespaceReturn (line 103) | type UseNamespaceReturn = ReturnType<typeof useNamespace>;

FILE: hiauth-front/packages/@core/composables/src/use-priority-value.ts
  function usePriorityValue (line 16) | function usePriorityValue<
  function usePriorityValues (line 55) | function usePriorityValues<
  function useForwardPriorityValues (line 73) | function useForwardPriorityValues<

FILE: hiauth-front/packages/@core/composables/src/use-scroll-lock.ts
  constant SCROLL_FIXED_CLASS (line 9) | const SCROLL_FIXED_CLASS = `_scroll__fixed_`;
  function useScrollLock (line 11) | function useScrollLock() {

FILE: hiauth-front/packages/@core/composables/src/use-simple-locale/messages.ts
  type Locale (line 1) | type Locale = 'en-US' | 'zh-CN';

FILE: hiauth-front/packages/@core/composables/src/use-sortable.ts
  function useSortable (line 4) | function useSortable<T extends HTMLElement>(

FILE: hiauth-front/packages/@core/preferences/src/constants.ts
  type BuiltinThemePreset (line 3) | interface BuiltinThemePreset {
  constant BUILT_IN_THEME_PRESETS (line 10) | const BUILT_IN_THEME_PRESETS: BuiltinThemePreset[] = [
  constant COLOR_PRESETS (line 84) | const COLOR_PRESETS = [...BUILT_IN_THEME_PRESETS].slice(0, 7);

FILE: hiauth-front/packages/@core/preferences/src/preferences.ts
  constant STORAGE_KEY (line 19) | const STORAGE_KEY = 'preferences';
  constant STORAGE_KEY_LOCALE (line 20) | const STORAGE_KEY_LOCALE = `${STORAGE_KEY}-locale`;
  constant STORAGE_KEY_THEME (line 21) | const STORAGE_KEY_THEME = `${STORAGE_KEY}-theme`;
  class PreferenceManager (line 23) | class PreferenceManager {
    method constructor (line 32) | constructor() {
    method clearCache (line 42) | clearCache() {
    method getInitialPreferences (line 48) | public getInitialPreferences() {
    method getPreferences (line 52) | public getPreferences() {
    method initPreferences (line 61) | public async initPreferences({ namespace, overrides }: InitialOptions) {
    method resetPreferences (line 100) | resetPreferences() {
    method updatePreferences (line 116) | public updatePreferences(updates: DeepPartial<Preferences>) {
    method _savePreferences (line 130) | private _savePreferences(preference: Preferences) {
    method handleUpdates (line 141) | private handleUpdates(updates: DeepPartial<Preferences>) {
    method initPlatform (line 156) | private initPlatform() {
    method loadCachedPreferences (line 164) | private loadCachedPreferences() {
    method loadPreferences (line 172) | private loadPreferences(): Preferences {
    method setupWatcher (line 179) | private setupWatcher() {
    method updateColorMode (line 218) | private updateColorMode(preference: Preferences) {

FILE: hiauth-front/packages/@core/preferences/src/types.ts
  type SupportedLanguagesType (line 19) | type SupportedLanguagesType = 'en-US' | 'zh-CN';
  type AppPreferences (line 21) | interface AppPreferences {
  type BreadcrumbPreferences (line 90) | interface BreadcrumbPreferences {
  type CopyrightPreferences (line 103) | interface CopyrightPreferences {
  type FooterPreferences (line 120) | interface FooterPreferences {
  type HeaderPreferences (line 129) | interface HeaderPreferences {
  type LogoPreferences (line 142) | interface LogoPreferences {
  type NavigationPreferences (line 151) | interface NavigationPreferences {
  type SidebarPreferences (line 160) | interface SidebarPreferences {
  type ShortcutKeyPreferences (line 189) | interface ShortcutKeyPreferences {
  type TabbarPreferences (line 202) | interface TabbarPreferences {
  type ThemePreferences (line 229) | interface ThemePreferences {
  type TransitionPreferences (line 250) | interface TransitionPreferences {
  type WidgetPreferences (line 261) | interface WidgetPreferences {
  type Preferences (line 280) | interface Preferences {
  type PreferencesKeys (line 309) | type PreferencesKeys = keyof Preferences;
  type InitialOptions (line 311) | interface InitialOptions {

FILE: hiauth-front/packages/@core/preferences/src/update-css-variables.ts
  function updateCSSVariables (line 12) | function updateCSSVariables(preferences: Preferences) {
  function updateMainColorVariables (line 75) | function updateMainColorVariables(preference: Preferences) {
  function isDarkTheme (line 108) | function isDarkTheme(theme: string) {

FILE: hiauth-front/packages/@core/preferences/src/use-preferences.ts
  function usePreferences (line 8) | function usePreferences() {

FILE: hiauth-front/packages/@core/ui-kit/form-ui/src/config.ts
  constant DEFAULT_MODEL_PROP_NAME (line 23) | const DEFAULT_MODEL_PROP_NAME = 'modelValue';
  constant DEFAULT_FORM_COMMON_CONFIG (line 25) | const DEFAULT_FORM_COMMON_CONFIG: FormCommonConfig = {};
  constant COMPONENT_MAP (line 27) | const COMPONENT_MAP: Record<BaseFormComponentType, Component> = {
  constant COMPONENT_BIND_EVENT_MAP (line 37) | const COMPONENT_BIND_EVENT_MAP: Partial<
  function setupVbenForm (line 43) | function setupVbenForm<

FILE: hiauth-front/packages/@core/ui-kit/form-ui/src/form-api.ts
  function getDefaultState (line 29) | function getDefaultState(): VbenFormProps {
  class FormApi (line 52) | class FormApi {
    method constructor (line 72) | constructor(options: VbenFormProps = {}) {
    method getFieldComponentRef (line 101) | getFieldComponentRef<T = ComponentPublicInstance>(
    method getFocusedField (line 129) | getFocusedField() {
    method getLatestSubmissionValues (line 153) | getLatestSubmissionValues() {
    method getState (line 157) | getState() {
    method getValues (line 161) | async getValues<T = Recordable<any>>() {
    method isFieldValid (line 166) | async isFieldValid(fieldName: string) {
    method merge (line 171) | merge(formApi: FormApi) {
    method mount (line 211) | mount(formActions: FormActions, componentRefMap: Map<string, unknown>) {
    method removeSchemaByFields (line 227) | async removeSchemaByFields(fields: string[]) {
    method resetForm (line 241) | async resetForm(
    method resetValidate (line 249) | async resetValidate() {
    method scrollToFirstError (line 261) | scrollToFirstError(errors: Record<string, any> | string) {
    method setFieldValue (line 292) | async setFieldValue(field: string, value: any, shouldValidate?: boolea...
    method setLatestSubmissionValues (line 297) | setLatestSubmissionValues(values: null | Recordable<any>) {
    method setState (line 301) | setState(
    method setValues (line 321) | async setValues(
    method submitForm (line 354) | async submitForm(e?: Event) {
    method unmount (line 365) | unmount() {
    method updateSchema (line 373) | updateSchema(schema: Partial<FormSchema>[]) {
    method validate (line 407) | async validate(opts?: Partial<ValidationOptions>) {
    method validateAndSubmitForm (line 422) | async validateAndSubmitForm() {
    method validateField (line 434) | async validateField(fieldName: string, opts?: Partial<ValidationOption...
    method getForm (line 448) | private async getForm() {
    method updateState (line 580) | private updateState() {

FILE: hiauth-front/packages/@core/ui-kit/form-ui/src/form-render/dependencies.ts
  function useDependencies (line 15) | function useDependencies(

FILE: hiauth-front/packages/@core/ui-kit/form-ui/src/form-render/expandable.ts
  function useExpandable (line 14) | function useExpandable(props: FormRenderProps) {

FILE: hiauth-front/packages/@core/ui-kit/form-ui/src/form-render/helper.ts
  function getBaseRules (line 16) | function getBaseRules<
  function getDefaultValueInZodStack (line 32) | function getDefaultValueInZodStack(schema: ZodTypeAny): any {
  function isEventObjectLike (line 55) | function isEventObjectLike(obj: any) {

FILE: hiauth-front/packages/@core/ui-kit/form-ui/src/types.ts
  type FormLayout (line 11) | type FormLayout = 'horizontal' | 'inline' | 'vertical';
  type BaseFormComponentType (line 13) | type BaseFormComponentType =
  type Breakpoints (line 23) | type Breakpoints = '2xl:' | '3xl:' | '' | 'lg:' | 'md:' | 'sm:' | 'xl:';
  type GridCols (line 25) | type GridCols = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13;
  type WrapperClassType (line 27) | type WrapperClassType =
  type FormItemClassType (line 31) | type FormItemClassType =
  type FormFieldOptions (line 38) | type FormFieldOptions = Partial<
  type FormShape (line 47) | interface FormShape {
  type MaybeComponentPropKey (line 57) | type MaybeComponentPropKey =
  type MaybeComponentProps (line 64) | type MaybeComponentProps = { [K in MaybeComponentPropKey]?: any };
  type FormActions (line 66) | type FormActions = FormContext<GenericObject>;
  type CustomRenderType (line 68) | type CustomRenderType = (() => Component | string) | string;
  type FormSchemaRuleType (line 70) | type FormSchemaRuleType =
  type FormItemDependenciesCondition (line 77) | type FormItemDependenciesCondition<T = boolean | PromiseLike<boolean>> = (
  type FormItemDependenciesConditionWithRules (line 82) | type FormItemDependenciesConditionWithRules = (
  type FormItemDependenciesConditionWithProps (line 87) | type FormItemDependenciesConditionWithProps = (
  type FormItemDependencies (line 92) | interface FormItemDependencies {
  type ComponentProps (line 132) | type ComponentProps =
  type FormCommonConfig (line 139) | interface FormCommonConfig {
  type RenderComponentContentType (line 211) | type RenderComponentContentType = (
  type HandleSubmitFn (line 216) | type HandleSubmitFn = (
  type HandleResetFn (line 220) | type HandleResetFn = (
  type FieldMappingTime (line 224) | type FieldMappingTime = [
  type ArrayToStringFields (line 235) | type ArrayToStringFields = Array<
  type FormSchema (line 241) | interface FormSchema<
  type FormFieldProps (line 270) | interface FormFieldProps extends FormSchema {
  type FormRenderProps (line 274) | interface FormRenderProps<
  type ActionButtonOptions (line 344) | interface ActionButtonOptions extends VbenButtonProps {
  type VbenFormProps (line 350) | interface VbenFormProps<
  type ExtendedFormApi (line 432) | type ExtendedFormApi = FormApi & {
  type VbenFormAdapterOptions (line 438) | interface VbenFormAdapterOptions<

FILE: hiauth-front/packages/@core/ui-kit/form-ui/src/use-form-context.ts
  type ExtendFormProps (line 16) | type ExtendFormProps = VbenFormProps & { formApi: ExtendedFormApi };
  function useFormInitial (line 26) | function useFormInitial(

FILE: hiauth-front/packages/@core/ui-kit/form-ui/src/use-vben-form.ts
  function useVbenForm (line 14) | function useVbenForm<

FILE: hiauth-front/packages/@core/ui-kit/layout-ui/src/hooks/use-layout.ts
  function useLayout (line 7) | function useLayout(props: VbenLayoutProps) {

FILE: hiauth-front/packages/@core/ui-kit/layout-ui/src/vben-layout.ts
  type VbenLayoutProps (line 8) | interface VbenLayoutProps {

FILE: hiauth-front/packages/@core/ui-kit/menu-ui/src/components/normal-menu/normal-menu.ts
  type NormalMenuProps (line 3) | interface NormalMenuProps {

FILE: hiauth-front/packages/@core/ui-kit/menu-ui/src/hooks/use-menu-context.ts
  function createMenuContext (line 12) | function createMenuContext(injectMenuData: MenuProvider) {
  function createSubMenuContext (line 19) | function createSubMenuContext(injectSubMenuData: SubMenuProvider) {
  function useMenuContext (line 28) | function useMenuContext() {
  function useSubMenuContext (line 40) | function useSubMenuContext() {

FILE: hiauth-front/packages/@core/ui-kit/menu-ui/src/hooks/use-menu-scroll.ts
  type UseMenuScrollOptions (line 7) | interface UseMenuScrollOptions {
  function useMenuScroll (line 12) | function useMenuScroll(

FILE: hiauth-front/packages/@core/ui-kit/menu-ui/src/hooks/use-menu.ts
  function useMenu (line 7) | function useMenu() {
  function useMenuStyle (line 39) | function useMenuStyle(menu?: SubMenuProvider) {

FILE: hiauth-front/packages/@core/ui-kit/menu-ui/src/types.ts
  type MenuProps (line 5) | interface MenuProps {
  type SubMenuProps (line 58) | interface SubMenuProps extends MenuRecordBadgeRaw {
  type MenuItemProps (line 77) | interface MenuItemProps extends MenuRecordBadgeRaw {
  type MenuItemRegistered (line 96) | interface MenuItemRegistered {
  type MenuItemClicked (line 102) | interface MenuItemClicked {
  type MenuProvider (line 107) | interface MenuProvider {
  type SubMenuProvider (line 129) | interface SubMenuProvider {

FILE: hiauth-front/packages/@core/ui-kit/menu-ui/src/utils/index.ts
  type VNodeChildAtom (line 10) | type VNodeChildAtom = Exclude<VNodeChild, Array<any>>;
  type RawSlots (line 11) | type RawSlots = Exclude<VNodeNormalizedChildren, Array<any> | null | str...
  type FlattenVNodes (line 13) | type FlattenVNodes = Array<RawSlots | VNodeChildAtom>;
  function findComponentUpward (line 20) | function findComponentUpward(

FILE: hiauth-front/packages/@core/ui-kit/popup-ui/src/alert/AlertBuilder.ts
  function vbenAlert (line 30) | function vbenAlert(
  function vbenConfirm (line 109) | function vbenConfirm(
  function vbenPrompt (line 132) | async function vbenPrompt<T = any>(
  function clearAllAlerts (line 235) | function clearAllAlerts() {

FILE: hiauth-front/packages/@core/ui-kit/popup-ui/src/alert/alert.ts
  type IconType (line 7) | type IconType = 'error' | 'info' | 'question' | 'success' | 'warning';
  type BeforeCloseScope (line 9) | type BeforeCloseScope = {
  type AlertProps (line 13) | type AlertProps = {
  type PromptProps (line 54) | type PromptProps<T = any> = {
  type AlertContext (line 79) | type AlertContext = {
  function useAlertContext (line 93) | function useAlertContext() {

FILE: hiauth-front/packages/@core/ui-kit/popup-ui/src/drawer/__tests__/drawer-api.test.ts
  method state (line 12) | get state() {
  method constructor (line 19) | constructor(initialState: DrawerState, options: any) {
  method batch (line 24) | batch(cb: () => void) {
  method setState (line 28) | setState(fn: (prev: DrawerState) => DrawerState) {

FILE: hiauth-front/packages/@core/ui-kit/popup-ui/src/drawer/drawer-api.ts
  class DrawerApi (line 6) | class DrawerApi {
    method constructor (line 26) | constructor(options: DrawerApiOptions = {}) {
    method close (line 92) | async close() {
    method getData (line 105) | getData<T extends object = Record<string, any>>() {
    method lock (line 114) | lock(isLocked: boolean = true) {
    method onCancel (line 121) | onCancel() {
    method onClosed (line 132) | onClosed() {
    method onConfirm (line 141) | onConfirm() {
    method onOpened (line 148) | onOpened() {
    method open (line 154) | open() {
    method setData (line 158) | setData<T>(payload: T) {
    method setState (line 163) | setState(
    method unlock (line 180) | unlock() {

FILE: hiauth-front/packages/@core/ui-kit/popup-ui/src/drawer/drawer.ts
  type DrawerPlacement (line 7) | type DrawerPlacement = 'bottom' | 'left' | 'right' | 'top';
  type CloseIconPlacement (line 9) | type CloseIconPlacement = 'left' | 'right';
  type DrawerProps (line 11) | interface DrawerProps {
  type DrawerState (line 130) | interface DrawerState extends DrawerProps {
  type ExtendedDrawerApi (line 139) | type ExtendedDrawerApi = DrawerApi & {
  type DrawerApiOptions (line 145) | interface DrawerApiOptions extends DrawerState {

FILE: hiauth-front/packages/@core/ui-kit/popup-ui/src/drawer/use-drawer.ts
  constant USER_DRAWER_INJECT_KEY (line 22) | const USER_DRAWER_INJECT_KEY = Symbol('VBEN_DRAWER_INJECT');
  constant DEFAULT_DRAWER_PROPS (line 24) | const DEFAULT_DRAWER_PROPS: Partial<DrawerProps> = {};
  function setDefaultDrawerProps (line 26) | function setDefaultDrawerProps(props: Partial<DrawerProps>) {
  function useVbenDrawer (line 30) | function useVbenDrawer<
  function checkProps (line 120) | async function checkProps(api: ExtendedDrawerApi, attrs: Record<string, ...

FILE: hiauth-front/packages/@core/ui-kit/popup-ui/src/modal/__tests__/modal-api.test.ts
  method state (line 11) | get state() {
  method constructor (line 18) | constructor(initialState: ModalState, options: any) {
  method batch (line 23) | batch(cb: () => void) {
  method setState (line 27) | setState(fn: (prev: ModalState) => ModalState) {

FILE: hiauth-front/packages/@core/ui-kit/popup-ui/src/modal/modal-api.ts
  class ModalApi (line 6) | class ModalApi {
    method constructor (line 26) | constructor(options: ModalApiOptions = {}) {
    method close (line 102) | async close() {
    method getData (line 114) | getData<T extends object = Record<string, any>>() {
    method lock (line 123) | lock(isLocked = true) {
    method onCancel (line 130) | onCancel() {
    method onClosed (line 141) | onClosed() {
    method onConfirm (line 150) | onConfirm() {
    method onOpened (line 157) | onOpened() {
    method open (line 163) | open() {
    method setData (line 171) | setData<T>(payload: T) {
    method setState (line 176) | setState(
    method unlock (line 193) | unlock() {

FILE: hiauth-front/packages/@core/ui-kit/popup-ui/src/modal/modal.ts
  type ModalProps (line 7) | interface ModalProps {
  type ModalState (line 145) | interface ModalState extends ModalProps {
  type ExtendedModalApi (line 154) | type ExtendedModalApi = ModalApi & {
  type ModalApiOptions (line 160) | interface ModalApiOptions extends ModalState {

FILE: hiauth-front/packages/@core/ui-kit/popup-ui/src/modal/use-modal-draggable.ts
  function useModalDraggable (line 12) | function useModalDraggable(

FILE: hiauth-front/packages/@core/ui-kit/popup-ui/src/modal/use-modal.ts
  constant USER_MODAL_INJECT_KEY (line 18) | const USER_MODAL_INJECT_KEY = Symbol('VBEN_MODAL_INJECT');
  constant DEFAULT_MODAL_PROPS (line 20) | const DEFAULT_MODAL_PROPS: Partial<ModalProps> = {};
  function setDefaultModalProps (line 22) | function setDefaultModalProps(props: Partial<ModalProps>) {
  function useVbenModal (line 26) | function useVbenModal<TParentModalProps extends ModalProps = ModalProps>(
  function checkProps (line 129) | async function checkProps(api: ExtendedModalApi, attrs: Record<string, a...

FILE: hiauth-front/packages/@core/ui-kit/shadcn-ui/src/components/back-top/backtop.ts
  type BacktopProps (line 32) | interface BacktopProps {

FILE: hiauth-front/packages/@core/ui-kit/shadcn-ui/src/components/breadcrumb/types.ts
  type IBreadcrumb (line 5) | interface IBreadcrumb {
  type BreadcrumbProps (line 13) | interface BreadcrumbProps {

FILE: hiauth-front/packages/@core/ui-kit/shadcn-ui/src/components/button/button.ts
  type VbenButtonProps (line 7) | interface VbenButtonProps {
  type CustomRenderType (line 26) | type CustomRenderType = (() => Component | string) | string;
  type ValueType (line 28) | type ValueType = boolean | number | string;
  type VbenButtonGroupProps (line 30) | interface VbenButtonGroupProps

FILE: hiauth-front/packages/@core/ui-kit/shadcn-ui/src/components/context-menu/interface.ts
  type IContextMenuItem (line 3) | interface IContextMenuItem {

FILE: hiauth-front/packages/@core/ui-kit/shadcn-ui/src/components/dropdown-menu/interface.ts
  type VbenDropdownMenuItem (line 3) | interface VbenDropdownMenuItem {
  type DropdownMenuProps (line 28) | interface DropdownMenuProps {

FILE: hiauth-front/packages/@core/ui-kit/shadcn-ui/src/components/pin-input/types.ts
  type PinInputProps (line 1) | interface PinInputProps {

FILE: hiauth-front/packages/@core/ui-kit/shadcn-ui/src/components/segmented/types.ts
  type SegmentedItem (line 1) | interface SegmentedItem {

FILE: hiauth-front/packages/@core/ui-kit/shadcn-ui/src/ui/avatar/avatar.ts
  type AvatarVariants (line 22) | type AvatarVariants = VariantProps<typeof avatarVariant>;

FILE: hiauth-front/packages/@core/ui-kit/shadcn-ui/src/ui/badge/badge.ts
  type BadgeVariants (line 25) | type BadgeVariants = VariantProps<typeof badgeVariants>;

FILE: hiauth-front/packages/@core/ui-kit/shadcn-ui/src/ui/button/types.ts
  type ButtonVariantSize (line 1) | type ButtonVariantSize =
  type ButtonVariants (line 10) | type ButtonVariants =

FILE: hiauth-front/packages/@core/ui-kit/shadcn-ui/src/ui/form/injectionKeys.ts
  constant FORM_ITEM_INJECTION_KEY (line 4) | const FORM_ITEM_INJECTION_KEY = Symbol() as InjectionKey<string>;

FILE: hiauth-front/packages/@core/ui-kit/shadcn-ui/src/ui/form/useFormField.ts
  function useFormField (line 13) | function useFormField() {

FILE: hiauth-front/packages/@core/ui-kit/shadcn-ui/src/ui/sheet/sheet.ts
  type SheetVariants (line 24) | type SheetVariants = VariantProps<typeof sheetVariants>;

FILE: hiauth-front/packages/@core/ui-kit/shadcn-ui/src/ui/toggle/toggle.ts
  type ToggleVariants (line 27) | type ToggleVariants = VariantProps<typeof toggleVariants>;

FILE: hiauth-front/packages/@core/ui-kit/shadcn-ui/src/ui/tree/types.ts
  type TreeProps (line 6) | interface TreeProps {
  function treePropsDefaults (line 44) | function treePropsDefaults() {

FILE: hiauth-front/packages/@core/ui-kit/tabs-ui/src/types.ts
  type TabsEmits (line 4) | type TabsEmits = {
  type TabsProps (line 10) | interface TabsProps {
  type TabConfig (line 67) | interface TabConfig extends TabDefinition {

FILE: hiauth-front/packages/@core/ui-kit/tabs-ui/src/use-tabs-drag.ts
  function findParentElement (line 11) | function findParentElement(element: HTMLElement) {
  function useTabsDrag (line 18) | function useTabsDrag(props: TabsProps, emit: EmitType) {

FILE: hiauth-front/packages/@core/ui-kit/tabs-ui/src/use-tabs-view-scroll.ts
  type DomElement (line 9) | type DomElement = Element | null | undefined;
  function useTabsViewScroll (line 11) | function useTabsViewScroll(props: TabsProps) {

FILE: hiauth-front/packages/constants/src/core.ts
  constant LOGIN_PATH (line 4) | const LOGIN_PATH = '/auth/login';
  type LanguageOption (line 6) | interface LanguageOption {
  constant SUPPORT_LANGUAGES (line 14) | const SUPPORT_LANGUAGES: LanguageOption[] = [

FILE: hiauth-front/packages/effects/access/src/accessible.ts
  function generateAccessible (line 21) | async function generateAccessible(
  function generateRoutes (line 79) | async function generateRoutes(

FILE: hiauth-front/packages/effects/access/src/directive.ts
  function isAccessible (line 11) | function isAccessible(
  function registerAccessDirective (line 40) | function registerAccessDirective(app: App) {

FILE: hiauth-front/packages/effects/access/src/use-access.ts
  function useAccess (line 6) | function useAccess() {

FILE: hiauth-front/packages/effects/common-ui/src/components/captcha/hooks/useCaptchaPoints.ts
  function useCaptchaPoints (line 5) | function useCaptchaPoints() {

FILE: hiauth-front/packages/effects/common-ui/src/components/captcha/types.ts
  type CaptchaData (line 5) | interface CaptchaData {
  type CaptchaPoint (line 19) | interface CaptchaPoint extends CaptchaData {
  type PointSelectionCaptchaCardProps (line 25) | interface PointSelectionCaptchaCardProps {
  type PointSelectionCaptchaProps (line 57) | interface PointSelectionCaptchaProps
  type SliderCaptchaProps (line 76) | interface SliderCaptchaProps {
  type SliderRotateCaptchaProps (line 121) | interface SliderRotateCaptchaProps {
  type SliderTranslateCaptchaProps (line 162) | interface SliderTranslateCaptchaProps {
  type CaptchaVerifyPassingData (line 198) | interface CaptchaVerifyPassingData {
  type SliderCaptchaActionType (line 203) | interface SliderCaptchaActionType {
  type SliderRotateVerifyPassingData (line 207) | interface SliderRotateVerifyPassingData {

FILE: hiauth-front/packages/effects/common-ui/src/components/col-page/types.ts
  type ColPageProps (line 3) | interface ColPageProps extends PageProps {

FILE: hiauth-front/packages/effects/common-ui/src/components/count-to/types.ts
  type TransitionPresets (line 7) | type TransitionPresets = keyof typeof TransitionPresetsData;
  type CountToProps (line 13) | interface CountToProps {

FILE: hiauth-front/packages/effects/common-ui/src/components/icon-picker/icons.ts
  constant ICONS_MAP (line 6) | const ICONS_MAP: Recordable<string[]> = {};
  type IconifyResponse (line 8) | interface IconifyResponse {
  constant PENDING_REQUESTS (line 17) | const PENDING_REQUESTS: Recordable<Promise<string[]>> = {};
  function fetchIconsData (line 26) | async function fetchIconsData(prefix: string): Promise<string[]> {

FILE: hiauth-front/packages/effects/common-ui/src/components/json-viewer/types.ts
  type JsonViewerProps (line 1) | interface JsonViewerProps {
  type JsonViewerAction (line 26) | interface JsonViewerAction {
  type JsonViewerValue (line 32) | interface JsonViewerValue {
  type JsonViewerToggle (line 39) | interface JsonViewerToggle {

FILE: hiauth-front/packages/effects/common-ui/src/components/loading/directive.ts
  constant LOADING_INSTANCE_KEY (line 8) | const LOADING_INSTANCE_KEY = Symbol('loading');
  constant SPINNER_INSTANCE_KEY (line 9) | const SPINNER_INSTANCE_KEY = Symbol('spinner');
  constant CLASS_NAME_RELATIVE (line 11) | const CLASS_NAME_RELATIVE = 'spinner-parent--relative';
  method mounted (line 14) | mounted(el, binding) {
  method unmounted (line 21) | unmounted(el) {
  method updated (line 30) | updated(el, binding) {
  function getOptions (line 49) | function getOptions(binding: DirectiveBinding) {
  method mounted (line 60) | mounted(el, binding) {
  method unmounted (line 67) | unmounted(el) {
  method updated (line 76) | updated(el, binding) {
  type loadingDirectiveParams (line 95) | type loadingDirectiveParams = {
  function registerLoadingDirective (line 107) | function registerLoadingDirective(

FILE: hiauth-front/packages/effects/common-ui/src/components/page/types.ts
  type PageProps (line 1) | interface PageProps {

FILE: hiauth-front/packages/effects/common-ui/src/components/tippy/directive.ts
  function useTippyDirective (line 5) | function useTippyDirective(isDark: ComputedRef<boolean>) {

FILE: hiauth-front/packages/effects/common-ui/src/components/tippy/index.ts
  type TippyProps (line 21) | type TippyProps = Partial<
  function initTippy (line 34) | function initTippy(app: App<Element>, options?: DefaultProps) {

FILE: hiauth-front/packages/effects/common-ui/src/ui/about/about.ts
  type AboutProps (line 3) | interface AboutProps {
  type DescriptionItem (line 9) | interface DescriptionItem {

FILE: hiauth-front/packages/effects/common-ui/src/ui/authentication/types.ts
  type AuthenticationProps (line 1) | interface AuthenticationProps {

FILE: hiauth-front/packages/effects/common-ui/src/ui/dashboard/typing.ts
  type AnalysisOverviewItem (line 3) | interface AnalysisOverviewItem {
  type WorkbenchProjectItem (line 11) | interface WorkbenchProjectItem {
  type WorkbenchTrendItem (line 21) | interface WorkbenchTrendItem {
  type WorkbenchTodoItem (line 28) | interface WorkbenchTodoItem {
  type WorkbenchQuickNavItem (line 35) | interface WorkbenchQuickNavItem {

FILE: hiauth-front/packages/effects/common-ui/src/ui/fallback/fallback.ts
  type FallbackProps (line 1) | interface FallbackProps {

FILE: hiauth-front/packages/effects/hooks/src/use-app-config.ts
  function useAppConfig (line 9) | function useAppConfig(

FILE: hiauth-front/packages/effects/hooks/src/use-content-maximize.ts
  function useContentMaximize (line 5) | function useContentMaximize() {

FILE: hiauth-front/packages/effects/hooks/src/use-design-tokens.ts
  function useAntdDesignTokens (line 10) | function useAntdDesignTokens() {
  function useNaiveDesignTokens (line 77) | function useNaiveDesignTokens() {
  function useElementPlusDesignTokens (line 163) | function useElementPlusDesignTokens() {

FILE: hiauth-front/packages/effects/hooks/src/use-hover-toggle.ts
  type HoverDelayOptions (line 11) | interface HoverDelayOptions {
  constant DEFAULT_LEAVE_DELAY (line 18) | const DEFAULT_LEAVE_DELAY = 500;
  constant DEFAULT_ENTER_DELAY (line 19) | const DEFAULT_ENTER_DELAY = 0;
  function useHoverToggle (line 27) | function useHoverToggle(

FILE: hiauth-front/packages/effects/hooks/src/use-pagination.ts
  function pagination (line 13) | function pagination<T = any>(list: T[], pageNo: number, pageSize: number...
  function usePagination (line 25) | function usePagination<T = any>(list: Ref<T[]>, pageSize: number) {

FILE: hiauth-front/packages/effects/hooks/src/use-refresh.ts
  function useRefresh (line 5) | function useRefresh() {

FILE: hiauth-front/packages/effects/hooks/src/use-tabs.ts
  function useTabs (line 8) | function useTabs() {

FILE: hiauth-front/packages/effects/hooks/src/use-watermark.ts
  function useWatermark (line 40) | function useWatermark() {

FILE: hiauth-front/packages/effects/layouts/src/authentication/types.ts
  type ToolbarType (line 1) | type ToolbarType = 'color' | 'language' | 'layout' | 'theme';

FILE: hiauth-front/packages/effects/layouts/src/basic/content/use-content-spinner.ts
  function useContentSpinner (line 6) | function useContentSpinner() {

FILE: hiauth-front/packages/effects/layouts/src/basic/menu/use-extra-menu.ts
  function useExtraMenu (line 14) | function useExtraMenu(useRootMenus?: ComputedRef<MenuRecordRaw[]>) {

FILE: hiauth-front/packages/effects/layouts/src/basic/menu/use-mixed-menu.ts
  function useMixedMenu (line 12) | function useMixedMenu() {

FILE: hiauth-front/packages/effects/layouts/src/basic/menu/use-navigation.ts
  function useNavigation (line 7) | function useNavigation() {

FILE: hiauth-front/packages/effects/layouts/src/basic/tabbar/use-tabbar.ts
  function useTabbar (line 28) | function useTabbar() {

FILE: hiauth-front/packages/effects/layouts/src/widgets/notification/types.ts
  type NotificationItem (line 1) | interface NotificationItem {

FILE: hiauth-front/packages/effects/layouts/src/widgets/preferences/use-open-preferences.ts
  function useOpenPreferences (line 5) | function useOpenPreferences() {

FILE: hiauth-front/packages/effects/plugins/src/echarts/echarts.ts
  type ECOption (line 32) | type ECOption = ComposeOption<

FILE: hiauth-front/packages/effects/plugins/src/echarts/use-echarts.ts
  type EchartsUIType (line 23) | type EchartsUIType = typeof EchartsUI | undefined;
  type EchartsThemeType (line 25) | type EchartsThemeType = 'dark' | 'light' | null;
  function useEcharts (line 27) | function useEcharts(chartRef: Ref<EchartsUIType>) {

FILE: hiauth-front/packages/effects/plugins/src/motion/types.ts
  type MotionPreset (line 26) | type MotionPreset = (typeof MotionPresets)[number];

FILE: hiauth-front/packages/effects/plugins/src/vxe-table/api.ts
  function getDefaultState (line 18) | function getDefaultState(): VxeGridProps {
  class VxeGridApi (line 29) | class VxeGridApi<T extends Record<string, any> = any> {
    method constructor (line 42) | constructor(options: VxeGridProps = {}) {
    method mount (line 61) | mount(instance: null | VxeGridInstance, formApi: ExtendedFormApi) {
    method query (line 70) | async query(params: Record<string, any> = {}) {
    method reload (line 78) | async reload(params: Record<string, any> = {}) {
    method setGridOptions (line 86) | setGridOptions(options: Partial<VxeGridProps['gridOptions']>) {
    method setLoading (line 92) | setLoading(isLoading: boolean) {
    method setState (line 100) | setState(
    method toggleSearchForm (line 114) | toggleSearchForm(show?: boolean) {
    method unmount (line 124) | unmount() {

FILE: hiauth-front/packages/effects/plugins/src/vxe-table/extends.ts
  function extendProxyOptions (line 9) | function extendProxyOptions(
  function extendProxyOption (line 26) | function extendProxyOption(
  function extendsDefaultFormatter (line 69) | function extendsDefaultFormatter(vxeUI: VxeUIExport) {

FILE: hiauth-front/packages/effects/plugins/src/vxe-table/init.ts
  function initVxeTable (line 63) | function initVxeTable() {
  function setupVbenVxeTable (line 103) | function setupVbenVxeTable(setupOptions: SetupVxeTable) {

FILE: hiauth-front/packages/effects/plugins/src/vxe-table/types.ts
  type VxePaginationInfo (line 18) | interface VxePaginationInfo {
  type ToolbarConfigOptions (line 24) | interface ToolbarConfigOptions extends VxeGridPropTypes.ToolbarConfig {
  type VxeTableGridOptions (line 29) | interface VxeTableGridOptions<T = any> extends VxeTableGridProps<T> {
  type SeparatorOptions (line 34) | interface SeparatorOptions {
  type VxeGridProps (line 39) | interface VxeGridProps<
  type ExtendedVxeGridApi (line 81) | type ExtendedVxeGridApi<
  type SetupVxeTable (line 90) | interface SetupVxeTable {

FILE: hiauth-front/packages/effects/plugins/src/vxe-table/use-vxe-grid.ts
  type FilteredSlots (line 16) | type FilteredSlots<T> = {
  function useVbenVxeGrid (line 22) | function useVbenVxeGrid<
  type UseVbenVxeGrid (line 70) | type UseVbenVxeGrid = typeof useVbenVxeGrid;

FILE: hiauth-front/packages/effects/request/src/request-client/modules/downloader.ts
  type DownloadRequestConfig (line 4) | type DownloadRequestConfig = {
  class FileDownloader (line 13) | class FileDownloader {
    method constructor (line 16) | constructor(client: RequestClient) {
    method download (line 25) | public async download<T = Blob>(

FILE: hiauth-front/packages/effects/request/src/request-client/modules/interceptor.ts
  class InterceptorManager (line 18) | class InterceptorManager {
    method constructor (line 21) | constructor(instance: AxiosInstance) {
    method addRequestInterceptor (line 25) | addRequestInterceptor({
    method addResponseInterceptor (line 32) | addResponseInterceptor<T = any>({

FILE: hiauth-front/packages/effects/request/src/request-client/modules/sse.test.ts
  method decode (line 15) | decode(value: Uint8Array, opts?: any) {

FILE: hiauth-front/packages/effects/request/src/request-client/modules/sse.ts
  class SSE (line 9) | class SSE {
    method constructor (line 12) | constructor(client: RequestClient) {
    method postSSE (line 16) | public async postSSE(
    method requestSSE (line 33) | public async requestSSE(
  function safeJoinUrl (line 117) | function safeJoinUrl(baseUrl: string | undefined, url: string): string {

FILE: hiauth-front/packages/effects/request/src/request-client/modules/uploader.ts
  class FileUploader (line 6) | class FileUploader {
    method constructor (line 9) | constructor(client: RequestClient) {
    method upload (line 13) | public async upload<T = any>(

FILE: hiauth-front/packages/effects/request/src/request-client/request-client.ts
  function getParamsSerializer (line 15) | function getParamsSerializer(
  class RequestClient (line 39) | class RequestClient {
    method constructor (line 58) | constructor(options: RequestClientOptions = {}) {
    method delete (line 99) | public delete<T = any>(
    method get (line 109) | public get<T = any>(url: string, config?: RequestClientConfig): Promis...
    method getBaseUrl (line 116) | public getBaseUrl() {
    method post (line 123) | public post<T = any>(
    method put (line 134) | public put<T = any>(
    method request (line 145) | public async request<T>(

FILE: hiauth-front/packages/effects/request/src/request-client/types.ts
  type ExtendOptions (line 8) | type ExtendOptions<T = any> = {
  type RequestClientConfig (line 30) | type RequestClientConfig<T = any> = AxiosRequestConfig<T> & ExtendOption...
  type RequestResponse (line 32) | type RequestResponse<T = any> = AxiosResponse<T> & {
  type RequestContentType (line 36) | type RequestContentType =
  type RequestClientOptions (line 42) | type RequestClientOptions = CreateAxiosDefaults & ExtendOptions;
  type SseRequestOptions (line 47) | interface SseRequestOptions extends RequestInit {
  type RequestInterceptorConfig (line 52) | interface RequestInterceptorConfig {
  type ResponseInterceptorConfig (line 61) | interface ResponseInterceptorConfig<T = any> {
  type MakeErrorMessageFn (line 68) | type MakeErrorMessageFn = (message: string, error: any) => void;
  type HttpResponse (line 70) | interface HttpResponse<T = any> {

FILE: hiauth-front/packages/icons/src/svg/load.ts
  function parseSvg (line 11) | function parseSvg(svgData: string): IconifyIconStructure {
  function loadSvgIcons (line 41) | async function loadSvgIcons() {

FILE: hiauth-front/packages/locales/src/i18n.ts
  function loadLocalesMap (line 37) | function loadLocalesMap(modules: Record<string, () => Promise<unknown>>) {
  function loadLocalesMapFromDir (line 55) | function loadLocalesMapFromDir(
  function setI18nLanguage (line 96) | function setI18nLanguage(locale: Locale) {
  function setupI18n (line 102) | async function setupI18n(app: App, options: LocaleSetupOptions = {}) {
  function loadLocaleMessages (line 123) | async function loadLocaleMessages(lang: SupportedLanguagesType) {

FILE: hiauth-front/packages/locales/src/typing.ts
  type SupportedLanguagesType (line 1) | type SupportedLanguagesType = 'en-US' | 'zh-CN';
  type ImportLocaleFn (line 3) | type ImportLocaleFn = () => Promise<{ default: Record<string, string> }>;
  type LoadMessageFn (line 5) | type LoadMessageFn = (
  type LocaleSetupOptions (line 9) | interface LocaleSetupOptions {

FILE: hiauth-front/packages/preferences/src/index.ts
  function defineOverridesPreferences (line 11) | function defineOverridesPreferences(preferences: DeepPartial<Preferences...

FILE: hiauth-front/packages/stores/src/modules/access.ts
  type AccessToken (line 7) | type AccessToken = null | string;
  type AccessState (line 9) | interface AccessState {
  method getMenuByPath (line 53) | getMenuByPath(path: string) {
  method lockScreen (line 72) | lockScreen(password: string) {
  method setAccessCodes (line 76) | setAccessCodes(codes: string[]) {
  method setAccessMenus (line 79) | setAccessMenus(menus: MenuRecordRaw[]) {
  method setAccessRoutes (line 82) | setAccessRoutes(routes: RouteRecordRaw[]) {
  method setAccessToken (line 85) | setAccessToken(token: AccessToken) {
  method setIsAccessChecked (line 88) | setIsAccessChecked(isAccessChecked: boolean) {
  method setLoginExpired (line 91) | setLoginExpired(loginExpired: boolean) {
  method setRefreshToken (line 94) | setRefreshToken(token: AccessToken) {
  method unlockScreen (line 97) | unlockScreen() {

FILE: hiauth-front/packages/stores/src/modules/tabbar.ts
  type TabbarState (line 21) | interface TabbarState {
  method _bulkCloseByKeys (line 60) | async _bulkCloseByKeys(keys: string[]) {
  method _close (line 72) | _close(tab: TabDefinition) {
  method _goToDefaultTab (line 82) | async _goToDefaultTab(router: Router) {
  method _goToTab (line 96) | async _goToTab(tab: TabDefinition, router: Router) {
  method addTab (line 109) | addTab(routeTab: TabDefinition): TabDefinition {
  method closeAllTabs (line 174) | async closeAllTabs(router: Router) {
  method closeLeftTabs (line 184) | async closeLeftTabs(tab: TabDefinition) {
  method closeOtherTabs (line 205) | async closeOtherTabs(tab: TabDefinition) {
  method closeRightTabs (line 229) | async closeRightTabs(tab: TabDefinition) {
  method closeTab (line 250) | async closeTab(tab: TabDefinition, router: Router) {
  method closeTabByKey (line 283) | async closeTabByKey(key: string, router: Router) {
  method getTabByKey (line 302) | getTabByKey(key: string) {
  method openTabInNewWindow (line 311) | async openTabInNewWindow(tab: TabDefinition) {
  method pinTab (line 319) | async pinTab(tab: TabDefinition) {
  method refresh (line 340) | async refresh(router: Router | string) {
  method refreshByName (line 364) | async refreshByName(name: string) {
  method resetTabTitle (line 373) | async resetTabTitle(tab: TabDefinition) {
  method setAffixTabs (line 388) | setAffixTabs(tabs: RouteRecordNormalized[]) {
  method setMenuList (line 399) | setMenuList(list: string[]) {
  method setTabTitle (line 421) | async setTabTitle(tab: TabDefinition, title: ComputedRef<string> | strin...
  method setUpdateTime (line 430) | setUpdateTime() {
  method sortTabs (line 438) | async sortTabs(oldIndex: number, newIndex: number) {
  method toggleTabPin (line 452) | async toggleTabPin(tab: TabDefinition) {
  method unpinTab (line 462) | async unpinTab(tab: TabDefinition) {
  method updateCacheTabs (line 482) | async updateCacheTabs() {
  method affixTabs (line 504) | affixTabs(): TabDefinition[] {
  method getCachedTabs (line 513) | getCachedTabs(): string[] {
  method getExcludeCachedTabs (line 516) | getExcludeCachedTabs(): string[] {
  method getMenuList (line 519) | getMenuList(): string[] {
  method getTabs (line 522) | getTabs(): TabDefinition[] {
  function cloneTab (line 565) | function cloneTab(route: TabDefinition): TabDefinition {
  function isAffixTab (line 590) | function isAffixTab(tab: TabDefinition) {
  function isTabShown (line 598) | function isTabShown(tab: TabDefinition) {
  function getTabKey (line 607) | function getTabKey(tab: RouteLocationNormalized | RouteRecordNormalized) {
  function getTabKeyFromTab (line 636) | function getTabKeyFromTab(tab: TabDefinition): string {
  function equalTab (line 645) | function equalTab(a: TabDefinition, b: TabDefinition) {
  function routeToTab (line 649) | function routeToTab(route: RouteRecordNormalized) {

FILE: hiauth-front/packages/stores/src/modules/user.ts
  type BasicUserInfo (line 3) | interface BasicUserInfo {
  type AccessState (line 27) | interface AccessState {
  method setUserInfo (line 43) | setUserInfo(userInfo: BasicUserInfo | null) {
  method setUserRoles (line 50) | setUserRoles(roles: string[]) {

FILE: hiauth-front/packages/stores/src/setup.ts
  type InitStoreOptions (line 10) | interface InitStoreOptions {
  function initStores (line 20) | async function initStores(app: App, options: InitStoreOptions) {
  function resetAllStores (line 51) | function resetAllStores() {

FILE: hiauth-front/packages/types/global.d.ts
  type RouteMeta (line 7) | interface RouteMeta extends IRouteMeta {}
  type VbenAdminProAppConfigRaw (line 10) | interface VbenAdminProAppConfigRaw {
  type AuthConfig (line 16) | interface AuthConfig {
  type ApplicationConfig (line 23) | interface ApplicationConfig {
  type Window (line 29) | interface Window {

FILE: hiauth-front/packages/types/src/user.ts
  type UserInfo (line 4) | interface UserInfo extends BasicUserInfo {

FILE: hiauth-front/packages/utils/src/helpers/find-menu-by-path.ts
  function findMenuByPath (line 3) | function findMenuByPath(
  function findRootMenuByPath (line 24) | function findRootMenuByPath(menus: MenuRecordRaw[], path?: string, level...

FILE: hiauth-front/packages/utils/src/helpers/generate-menus.ts
  function generateMenus (line 17) | function generateMenus(

FILE: hiauth-front/packages/utils/src/helpers/generate-routes-backend.ts
  function generateRoutesByBackend (line 14) | async function generateRoutesByBackend(
  function convertRoutes (line 40) | function convertRoutes(
  function normalizeViewPath (line 74) | function normalizeViewPath(path: string): string {

FILE: hiauth-front/packages/utils/src/helpers/generate-routes-frontend.ts
  function generateRoutesByFrontend (line 8) | async function generateRoutesByFrontend(
  function hasAuthority (line 36) | function hasAuthority(route: RouteRecordRaw, access: string[]) {
  function menuHasVisibleWithForbidden (line 50) | function menuHasVisibleWithForbidden(route: RouteRecordRaw) {

FILE: hiauth-front/packages/utils/src/helpers/get-popup-container.ts
  function getPopupContainer (line 6) | function getPopupContainer(node?: HTMLElement): HTMLElement {

FILE: hiauth-front/packages/utils/src/helpers/merge-route-modules.ts
  type RouteModuleType (line 4) | interface RouteModuleType {
  function mergeRouteModules (line 13) | function mergeRouteModules(

FILE: hiauth-front/packages/utils/src/helpers/reset-routes.ts
  function resetStaticRoutes (line 8) | function resetStaticRoutes(router: Router, routes: RouteRecordRaw[]) {

FILE: hiauth-front/packages/utils/src/helpers/unmount-global-loading.ts
  function unmountGlobalLoading (line 8) | function unmountGlobalLoading() {

FILE: hiauth-front/playground/__tests__/e2e/common/auth.ts
  function authLogin (line 5) | async function authLogin(page: Page) {

FILE: hiauth-front/playground/src/adapter/component/index.ts
  type ComponentType (line 108) | type ComponentType =
  function initComponentAdapter (line 136) | async function initComponentAdapter() {

FILE: hiauth-front/playground/src/adapter/form.ts
  function initSetupVbenForm (line 11) | async function initSetupVbenForm() {
  type VbenFormSchema (line 46) | type VbenFormSchema = FormSchema<ComponentType>;

FILE: hiauth-front/playground/src/adapter/vxe-table.ts
  method renderTableDefault (line 65) | renderTableDefault(_renderOpts, params) {
  method renderTableDefault (line 73) | renderTableDefault(renderOpts) {
  method renderTableDefault (line 85) | renderTableDefault({ options, props }, { column, row }) {
  method renderTableDefault (line 104) | renderTableDefault({ attrs, props }, { column, row }) {
  method renderTableDefault (line 135) | renderTableDefault({ attrs, options, props }, { column, row }) {
  type OnActionClickParams (line 290) | type OnActionClickParams<T = Recordable<any>> = {
  type OnActionClickFn (line 294) | type OnActionClickFn<T = Recordable<any>> = (

FILE: hiauth-front/playground/src/api/core/auth.ts
  type LoginParams (line 5) | interface LoginParams {
  type LoginResult (line 11) | interface LoginResult {
  type RefreshTokenResult (line 15) | interface RefreshTokenResult {
  function loginApi (line 24) | async function loginApi(data: AuthApi.LoginParams) {
  function refreshTokenApi (line 33) | async function refreshTokenApi() {
  function logoutApi (line 46) | async function logoutApi() {
  function getAccessCodesApi (line 55) | async function getAccessCodesApi() {

FILE: hiauth-front/playground/src/api/core/menu.ts
  function getAllMenusApi (line 8) | async function getAllMenusApi() {

FILE: hiauth-front/playground/src/api/core/user.ts
  function getUserInfoApi (line 8) | async function getUserInfoApi() {

FILE: hiauth-front/playground/src/api/examples/download.ts
  function downloadFile1 (line 9) | async function downloadFile1() {
  function downloadFile2 (line 19) | async function downloadFile2() {

FILE: hiauth-front/playground/src/api/examples/json-bigint.ts
  function getBigIntData (line 6) | async function getBigIntData() {

FILE: hiauth-front/playground/src/api/examples/params.ts
  function getParamsData (line 8) | async function getParamsData(

FILE: hiauth-front/playground/src/api/examples/status.ts
  function getMockStatusApi (line 6) | async function getMockStatusApi(status: string) {

FILE: hiauth-front/playground/src/api/examples/table.ts
  type PageFetchParams (line 4) | interface PageFetchParams {
  function getExampleTableApi (line 14) | async function getExampleTableApi(params: DemoTableApi.PageFetchParams) {

FILE: hiauth-front/playground/src/api/examples/upload.ts
  type UploadFileParams (line 3) | interface UploadFileParams {
  function upload_file (line 9) | async function upload_file({

FILE: hiauth-front/playground/src/api/request.ts
  function createRequestClient (line 26) | function createRequestClient(baseURL: string, options?: RequestClientOpt...
  type PageFetchParams (line 125) | interface PageFetchParams {

FILE: hiauth-front/playground/src/api/system/dept.ts
  type SystemDept (line 4) | interface SystemDept {
  function getDeptList (line 17) | async function getDeptList() {
  function createDept (line 27) | async function createDept(
  function updateDept (line 39) | async function updateDept(
  function deleteDept (line 50) | async function deleteDept(id: string) {

FILE: hiauth-front/playground/src/api/system/menu.ts
  type SystemMenu (line 25) | interface SystemMenu {
  function getMenuList (line 96) | async function getMenuList() {
  function isMenuNameExists (line 102) | async function isMenuNameExists(
  function isMenuPathExists (line 111) | async function isMenuPathExists(
  function createMenu (line 124) | async function createMenu(
  function updateMenu (line 136) | async function updateMenu(
  function deleteMenu (line 147) | async function deleteMenu(id: string) {

FILE: hiauth-front/playground/src/api/system/role.ts
  type SystemRole (line 6) | interface SystemRole {
  function getRoleList (line 19) | async function getRoleList(params: Recordable<any>) {
  function createRole (line 30) | async function createRole(data: Omit<SystemRoleApi.SystemRole, 'id'>) {
  function updateRole (line 40) | async function updateRole(
  function deleteRole (line 51) | async function deleteRole(id: string) {

FILE: hiauth-front/playground/src/bootstrap.ts
  function bootstrap (line 19) | async function bootstrap(namespace: string) {

FILE: hiauth-front/playground/src/locales/index.ts
  function loadMessages (line 33) | async function loadMessages(lang: SupportedLanguagesType) {
  function loadThirdPartyMessage (line 45) | async function loadThirdPartyMessage(lang: SupportedLanguagesType) {
  function loadDayjsLocale (line 53) | async function loadDayjsLocale(lang: SupportedLanguagesType) {
  function loadAntdLocale (line 80) | async function loadAntdLocale(lang: SupportedLanguagesType) {
  function setupI18n (line 93) | async function setupI18n(app: App, options: LocaleSetupOptions = {}) {

FILE: hiauth-front/playground/src/main.ts
  function initApplication (line 9) | async function initApplication() {

FILE: hiauth-front/playground/src/router/access.ts
  function generateAccess (line 17) | async function generateAccess(options: GenerateMenuAndRoutesOptions) {

FILE: hiauth-front/playground/src/router/guard.ts
  function setupCommonGuard (line 17) | function setupCommonGuard(router: Router) {
  function setupAccessGuard (line 46) | function setupAccessGuard(router: Router) {
  function createRouterGuard (line 129) | function createRouterGuard(router: Router) {

FILE: hiauth-front/playground/src/store/auth.ts
  function authLogin (line 29) | async function authLogin(
  function logout (line 81) | async function logout(redirect: boolean = true) {
  function fetchUserInfo (line 102) | async function fetchUserInfo() {
  function $reset (line 109) | function $reset() {

FILE: hiauth-front/playground/src/views/demos/features/vue-query/typing.ts
  type IProducts (line 1) | interface IProducts {

FILE: hiauth-front/playground/src/views/examples/vxe-table/table-data.ts
  type TableRowData (line 1) | interface TableRowData {
  constant MOCK_TABLE_DATA (line 12) | const MOCK_TABLE_DATA: TableRowData[] = (() => {
  constant MOCK_TREE_TABLE_DATA (line 27) | const MOCK_TREE_TABLE_DATA = [

FILE: hiauth-front/playground/src/views/system/dept/data.ts
  function useSchema (line 14) | function useSchema(): VbenFormSchema[] {
  function useColumns (line 77) | function useColumns(

FILE: hiauth-front/playground/src/views/system/menu/data.ts
  function getMenuTypeOptions (line 6) | function getMenuTypeOptions() {
  function useColumns (line 24) | function useColumns(

FILE: hiauth-front/playground/src/views/system/role/data.ts
  function useFormSchema (line 7) | function useFormSchema(): VbenFormSchema[] {
  function useGridFormSchema (line 44) | function useGridFormSchema(): VbenFormSchema[] {
  function useColumns (line 77) | function useColumns<T = SystemRoleApi.SystemRole>(

FILE: hiauth-front/scripts/clean.mjs
  constant CONCURRENCY_LIMIT (line 7) | const CONCURRENCY_LIMIT = 10;
  constant SKIP_DIRS (line 10) | const SKIP_DIRS = new Set(['.DS_Store', '.git', '.idea', '.vscode']);
  function processItem (line 20) | async function processItem(currentDir, item, targets, _depth) {
  function cleanTargetsRecursively (line 60) | async function cleanTargetsRecursively(currentDir, targets, depth = 0) {

FILE: hiauth-front/scripts/turbo-run/src/run.ts
  type RunOptions (line 5) | interface RunOptions {
  function run (line 9) | async function run(options: RunOptions) {

FILE: hiauth-front/scripts/vsh/src/check-circular/index.ts
  constant DEFAULT_CONFIG (line 10) | const DEFAULT_CONFIG = {
  type CircularDependencyResult (line 27) | type CircularDependencyResult = string[];
  type CheckCircularConfig (line 29) | interface CheckCircularConfig {
  type CommandOptions (line 35) | interface CommandOptions {
  function formatCircles (line 48) | function formatCircles(circles: CircularDependencyResult[]): void {
  function checkCircular (line 69) | async function checkCircular({
  function defineCheckCircularCommand (line 146) | function defineCheckCircularCommand(cac: CAC): void {

FILE: hiauth-front/scripts/vsh/src/check-dep/index.ts
  constant DEFAULT_CONFIG (line 8) | const DEFAULT_CONFIG = {
  type DepcheckResult (line 37) | interface DepcheckResult {
  type DepcheckConfig (line 43) | interface DepcheckConfig {
  type PackageInfo (line 49) | interface PackageInfo {
  function cleanDepcheckResult (line 60) | function cleanDepcheckResult(unused: DepcheckResult): void {
  function formatDepcheckResult (line 80) | function formatDepcheckResult(pkgName: string, unused: DepcheckResult): ...
  function runDepcheck (line 115) | async function runDepcheck(config: DepcheckConfig = {}): Promise<void> {
  function defineDepcheckCommand (line 167) | function defineDepcheckCommand(cac: CAC): void {

FILE: hiauth-front/scripts/vsh/src/code-workspace/index.ts
  constant CODE_WORKSPACE_FILE (line 16) | const CODE_WORKSPACE_FILE = join('vben-admin.code-workspace');
  type CodeWorkspaceCommandOptions (line 18) | interface CodeWorkspaceCommandOptions {
  function createCodeWorkspace (line 23) | async function createCodeWorkspace({
  function runCodeWorkspace (line 49) | async function runCodeWorkspace({
  function defineCodeWorkspaceCommand (line 65) | function defineCodeWorkspaceCommand(cac: CAC) {

FILE: hiauth-front/scripts/vsh/src/index.ts
  constant COMMAND_DESCRIPTIONS (line 13) | const COMMAND_DESCRIPTIONS = {
  function main (line 24) | async function main(): Promise<void> {

FILE: hiauth-front/scripts/vsh/src/lint/index.ts
  type LintCommandOptions (line 5) | interface LintCommandOptions {
  function runLint (line 12) | async function runLint({ format }: LintCommandOptions) {
  function defineLintCommand (line 40) | function defineLintCommand(cac: CAC) {

FILE: hiauth-front/scripts/vsh/src/publint/index.ts
  constant CACHE_FILE (line 21) | const CACHE_FILE = join(
  type PubLintCommandOptions (line 28) | interface PubLintCommandOptions {
  function getLintFiles (line 39) | async function getLintFiles(files: string[] = []) {
  function getCacheFile (line 54) | function getCacheFile() {
  function readCache (line 59) | async function readCache(cacheFile: string) {
  function runPublint (line 68) | async function runPublint(files: string[], { check }: PubLintCommandOpti...
  function printResult (line 115) | function printResult(
  function definePubLintCommand (line 177) | function definePubLintCommand(cac: CAC) {

FILE: hiauth-server/src/main/java/cn/hiauth/server/ServerStarter.java
  class ServerStarter (line 8) | @ComponentScan(basePackages = {"cn.hiauth.server", Constant.SCMS_BASIC_P...
    method main (line 12) | public static void main(String[] args) {

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/KeywordPageUserDto.java
  class KeywordPageUserDto (line 9) | @Data
    method toQueryWapper (line 14) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/PageDepDto.java
  class PageDepDto (line 10) | @Data
    method toQueryWapper (line 18) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/PageEmpDto.java
  class PageEmpDto (line 10) | @Data
    method toQueryWapper (line 20) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/PageRoleDto.java
  class PageRoleDto (line 10) | @Data
    method toQueryWapper (line 16) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/RegisterDto.java
  class RegisterDto (line 13) | @Data
    method toCorp (line 36) | public Corp toCorp() {
    method toUser (line 43) | public User toUser() {

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/app/AppCreateDto.java
  class AppCreateDto (line 11) | @Data
    method toDO (line 36) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/app/AppLimitDto.java
  class AppLimitDto (line 11) | @Data
    method toQueryWapper (line 21) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/app/AppPageDto.java
  class AppPageDto (line 11) | @Data
    method toQueryWapper (line 21) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/app/AppUpdateDto.java
  class AppUpdateDto (line 11) | @Data
    method getId (line 39) | @Override
    method toDO (line 44) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/appClient/AppClientCreateDto.java
  class AppClientCreateDto (line 12) | @Data
    method toDO (line 22) | @Override
    method toDos (line 27) | public List<CorpApp> toDos() {

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/appClient/AppClientDeleteDto.java
  class AppClientDeleteDto (line 7) | @Data

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/appClient/AppClientLimitDto.java
  class AppClientLimitDto (line 9) | @Data
    method toQueryWapper (line 18) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/appClient/AppClientPageDto.java
  class AppClientPageDto (line 10) | @Data
    method toQueryWapper (line 19) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/appClient/AppClientUpdateDto.java
  class AppClientUpdateDto (line 12) | @Data
    method getId (line 41) | @Override
    method toDO (line 46) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/appResource/AppResourceCreateDto.java
  class AppResourceCreateDto (line 13) | @Data
    method toDO (line 55) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/appResource/AppResourcePageDto.java
  class AppResourcePageDto (line 11) | @Data
    method toQueryWapper (line 39) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/appResource/AppResourceUpdateDto.java
  class AppResourceUpdateDto (line 13) | @Data
    method getId (line 55) | @Override
    method toDO (line 60) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/appResource/FindAppResourceIdsByRoleAndAppDto.java
  class FindAppResourceIdsByRoleAndAppDto (line 7) | @Data

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/corp/CorpCreateDto.java
  class CorpCreateDto (line 11) | @Data
    method toDO (line 24) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/corp/CorpPageDto.java
  class CorpPageDto (line 10) | @Data
    method toQueryWapper (line 19) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/corp/CorpUpdateDto.java
  class CorpUpdateDto (line 10) | @Data
    method getId (line 25) | @Override
    method toDO (line 30) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/dep/DepCreateDto.java
  class DepCreateDto (line 13) | @Data
    method toDO (line 43) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/dep/DepLimitDto.java
  class DepLimitDto (line 10) | @Data
    method toQueryWapper (line 19) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/dep/DepPageDto.java
  class DepPageDto (line 10) | @Data
    method toQueryWapper (line 31) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/dep/DepUpdateDto.java
  class DepUpdateDto (line 13) | @Data
    method getId (line 44) | @Override
    method toDO (line 49) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/dict/DictCreateDto.java
  class DictCreateDto (line 12) | @Data
    method toDO (line 40) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/dict/DictLimitDto.java
  class DictLimitDto (line 10) | @Data
    method toQueryWapper (line 22) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/dict/DictPageDto.java
  class DictPageDto (line 10) | @Data
    method toQueryWapper (line 31) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/dict/DictUpdateDto.java
  class DictUpdateDto (line 13) | @Data
    method getId (line 42) | @Override
    method toDO (line 47) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/emp/EmpCreateDto.java
  class EmpCreateDto (line 15) | @Data
    method toDO (line 47) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/emp/EmpPageDto.java
  class EmpPageDto (line 12) | @Data
    method toQueryWapper (line 36) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/emp/EmpUpdateDto.java
  class EmpUpdateDto (line 15) | @Data
    method getId (line 51) | @Override
    method toDO (line 56) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/login/CaptchaVerifyDto.java
  class CaptchaVerifyDto (line 5) | @Data

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/login/SmsCodeDto.java
  class SmsCodeDto (line 7) | @Data

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/login/SmsCodeLoginDto.java
  class SmsCodeLoginDto (line 8) | @Data

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/role/RoleAuthDto.java
  class RoleAuthDto (line 9) | @Data

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/role/RoleCreateDto.java
  class RoleCreateDto (line 13) | @Data
    method toDO (line 32) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/role/RoleLimitDto.java
  class RoleLimitDto (line 10) | @Data
    method toQueryWapper (line 19) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/role/RolePageDto.java
  class RolePageDto (line 10) | @Data
    method toQueryWapper (line 22) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/role/RoleUpdateDto.java
  class RoleUpdateDto (line 11) | @Data
    method getId (line 31) | @Override
    method toDO (line 36) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/user/UserCreateDto.java
  class UserCreateDto (line 14) | @Data
    method toDO (line 48) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/user/UserLimitDto.java
  class UserLimitDto (line 10) | @Data
    method toQueryWapper (line 19) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/user/UserPageDto.java
  class UserPageDto (line 10) | @Data
    method toQueryWapper (line 37) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/user/UserPwdUpdateDto.java
  class UserPwdUpdateDto (line 9) | @Data

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/dto/user/UserUpdateDto.java
  class UserUpdateDto (line 12) | @Data
    method getId (line 50) | @Override
    method toDO (line 55) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/vo/CommonTreeNodeVo.java
  class CommonTreeNodeVo (line 10) | @Data
    method convertToVo (line 18) | public static CommonTreeNodeVo convertToVo(AppResource o) {
    method convertToVo (line 25) | public static CommonTreeNodeVo convertToVo(Department o) {

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/vo/CorpAppVo.java
  class CorpAppVo (line 18) | @Data
    method convert (line 59) | public static CorpAppVo convert(Oauth2RegisteredClient o, App app) {
    method convert (line 84) | public static List<CorpAppVo> convert(List<Oauth2RegisteredClient> os,...
    method toPageVo (line 95) | public static PageVO<CorpAppVo> toPageVo(IPage<Oauth2RegisteredClient>...

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/vo/CorpResourceTreeNodeVo.java
  class CorpResourceTreeNodeVo (line 11) | @Data
    method convertToVo (line 24) | public static CorpResourceTreeNodeVo convertToVo(App o) {
    method convertToVo (line 32) | public static CorpResourceTreeNodeVo convertToVo(AppResource o) {

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/vo/CorpVo.java
  class CorpVo (line 11) | @Data
    method convert (line 22) | public static CorpVo convert(Corp corp) {
    method convert (line 34) | public static List<CorpVo> convert(List<Corp> corps) {
    method toPageVo (line 40) | public static PageVO<CorpVo> toPageVo(IPage<Corp> page) {

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/vo/CurrentLoginUserVo.java
  class CurrentLoginUserVo (line 9) | @Data

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/vo/EmpVo.java
  class EmpVo (line 14) | @Data
    method convert (line 47) | public static EmpVo convert(Employee o, Set<Long> depIds, Set<Long> ro...
    method convert (line 62) | public static List<EmpVo> convert(List<Employee> os) {
    method toPageVo (line 68) | public static PageVO<EmpVo> toPageVo(IPage<Employee> page) {

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/vo/IndexCorpAppVo.java
  class IndexCorpAppVo (line 11) | @Data
    method convert (line 18) | public static List<IndexCorpAppVo> convert(List<CorpAppInfo> cais) {

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/vo/SysMenuVo.java
  class SysMenuVo (line 10) | @Data

FILE: hiauth-server/src/main/java/cn/hiauth/server/api/vo/UserVo.java
  class UserVo (line 13) | @Data
    method convert (line 46) | public static UserVo convert(User o) {
    method convert (line 65) | public static List<UserVo> convert(List<User> os) {
    method toPageVo (line 71) | public static PageVO<UserVo> toPageVo(IPage<User> page) {

FILE: hiauth-server/src/main/java/cn/hiauth/server/config/AuthServerConfig.java
  class AuthServerConfig (line 60) | @Configuration
    method authorizationServerSecurityFilterChain (line 75) | @Bean
    method registeredClientRepository (line 124) | @Bean
    method authorizationService (line 134) | @Bean
    method authorizationConsentService (line 156) | @Bean
    method oidcUserInfoMapper (line 162) | @Bean
    method idTokenCustomizer (line 167) | @Bean
    method jwkSource (line 176) | @Bean
    method jwtDecoder (line 186) | @Bean
    method authorizationServerSettings (line 194) | @Bean
    method createDemoRegisteredClient (line 202) | private void createDemoRegisteredClient(JdbcRegisteredClientRepository...

FILE: hiauth-server/src/main/java/cn/hiauth/server/config/BeanConfig.java
  class BeanConfig (line 17) | @Slf4j
    method restTemplate (line 39) | @Bean
    method randomGenerator (line 47) | @Bean
    method smsUtils (line 55) | @Bean
    method jackson2ObjectMapperBuilderCustomizer (line 63) | @Bean
    method readOnlyFilterRegister (line 73) | @Bean

FILE: hiauth-server/src/main/java/cn/hiauth/server/config/DocConfig.java
  class DocConfig (line 10) | @Configuration
    method openApi (line 13) | @Bean

FILE: hiauth-server/src/main/java/cn/hiauth/server/config/SecurityConfig.java
  class SecurityConfig (line 44) | @Configuration(proxyBeanMethods = true)
    method passwordEncoder (line 61) | @Bean
    method securityFilterChain (line 69) | @Bean
    method securityContextRepository (line 112) | @Bean
    method authenticationSuccessHandler (line 121) | @Bean
    method authenticationFailureHandler (line 131) | @Bean
    method authenticationEntryPoint (line 139) | @Bean
    method httpSessionRequestCache (line 147) | @Bean
    method accountAuthenticationFilter (line 157) | @Bean
    method smsCodeAuthenticationFilter (line 170) | @Bean
    method qrCodeAuthenticationFilter (line 183) | @Bean
    method authenticationManager (line 193) | @Bean
    method webSecurityCustomizer (line 220) | @Bean

FILE: hiauth-server/src/main/java/cn/hiauth/server/config/WebMvcConfig.java
  class WebMvcConfig (line 11) | @Configuration
    method addResourceHandlers (line 17) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/config/props/AppProperties.java
  class AppProperties (line 10) | @Data

FILE: hiauth-server/src/main/java/cn/hiauth/server/config/props/WechatProperties.java
  class WechatProperties (line 9) | @Data

FILE: hiauth-server/src/main/java/cn/hiauth/server/config/rest/ApiExceptionAdvice.java
  class ApiExceptionAdvice (line 28) | @Slf4j
    method init (line 39) | @PostConstruct
    method handle (line 44) | @ResponseStatus(HttpStatus.OK)
    method handle (line 53) | @ResponseStatus(HttpStatus.OK)
    method handle (line 69) | @ResponseStatus(HttpStatus.OK)
    method handle (line 81) | @ResponseStatus(HttpStatus.OK)
    method handle (line 94) | @ResponseStatus(HttpStatus.OK)
    method handle (line 101) | @ResponseStatus(HttpStatus.OK)
    method logger (line 108) | private void logger(HttpServletRequest request, Exception e) {

FILE: hiauth-server/src/main/java/cn/hiauth/server/config/rest/ResourceAccessDeniedHandler.java
  class ResourceAccessDeniedHandler (line 12) | public class ResourceAccessDeniedHandler implements AccessDeniedHandler {
    method handle (line 13) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/config/rest/ResourceAuthenticationEntryPoint.java
  class ResourceAuthenticationEntryPoint (line 13) | public class ResourceAuthenticationEntryPoint implements AuthenticationE...
    method printError (line 17) | public static void printError(HttpServletResponse response, String msg) {
    method commence (line 39) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/config/rest/security/MySecurityUser.java
  class MySecurityUser (line 6) | @Data

FILE: hiauth-server/src/main/java/cn/hiauth/server/config/rest/security/ReadonlyFilter.java
  class ReadonlyFilter (line 22) | @Slf4j
    method ReadonlyFilter (line 30) | public ReadonlyFilter(String[] readonlyAccount) {
    method init (line 34) | @Override
    method doFilter (line 39) | @Override
    method doIt (line 50) | private void doIt(HttpServletRequest request, HttpServletResponse resp...
    method matcherAccount (line 77) | public boolean matcherAccount(String username) {
    method readOnlyUrl (line 86) | public boolean readOnlyUrl(String uri) {
    method printError (line 95) | private void printError(HttpServletRequest request, HttpServletRespons...
    method destroy (line 121) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/config/web/auth/AuthFailureHandler.java
  class AuthFailureHandler (line 15) | public class AuthFailureHandler implements AuthenticationFailureHandler {
    method onAuthenticationFailure (line 17) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/config/web/auth/AuthGrantedAuthority.java
  class AuthGrantedAuthority (line 7) | @Data
    method AuthGrantedAuthority (line 15) | public AuthGrantedAuthority() {
    method AuthGrantedAuthority (line 18) | public AuthGrantedAuthority(String authority) {
    method AuthGrantedAuthority (line 22) | public AuthGrantedAuthority(String code, String page, String api) {
    method getAuthority (line 28) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/config/web/auth/AuthGrantedAuthorityDeserializer.java
  class AuthGrantedAuthorityDeserializer (line 12) | public class AuthGrantedAuthorityDeserializer extends JsonDeserializer<A...
    method deserialize (line 14) | @Override
    method readJsonNode (line 24) | private JsonNode readJsonNode(JsonNode jsonNode, String field) {

FILE: hiauth-server/src/main/java/cn/hiauth/server/config/web/auth/AuthUser.java
  class AuthUser (line 13) | @Data
    method AuthUser (line 30) | public AuthUser() {
    method AuthUser (line 33) | public AuthUser(final Oauth2RegisteredClient client, final User user, ...
    method AuthUser (line 52) | public AuthUser(Long appId, Long cid, Long userId, Long empId, String ...
    method eraseCredentials (line 67) | @Override
    method getAuthorities (line 72) | @Override
    method getPassword (line 77) | @Override
    method getUsername (line 82) | @Override
    method isAccountNonExpired (line 87) | @Override
    method isAccountNonLocked (line 92) | @Override
    method isCredentialsNonExpired (line 97) | @Override
    method isEnabled (line 102) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/config/web/auth/AuthUserDeserializer.java
  class AuthUserDeserializer (line 14) | public class AuthUserDeserializer extends JsonDeserializer<AuthUser> {
    method deserialize (line 19) | @Override
    method readJsonNode (line 42) | private JsonNode readJsonNode(JsonNode jsonNode, String field) {

FILE: hiauth-server/src/main/java/cn/hiauth/server/config/web/auth/CustomAuthUserAttrs.java
  class CustomAuthUserAttrs (line 3) | public class CustomAuthUserAttrs {

FILE: hiauth-server/src/main/java/cn/hiauth/server/config/web/auth/CustomJdbcRegisteredClientRepository.java
  class CustomJdbcRegisteredClientRepository (line 11) | public class CustomJdbcRegisteredClientRepository extends JdbcRegistered...
    method CustomJdbcRegisteredClientRepository (line 31) | public CustomJdbcRegisteredClientRepository(JdbcOperations jdbcOperati...
    method findByClientIds (line 35) | public List<RegisteredClient> findByClientIds(Set<String> clientIds) {

FILE: hiauth-server/src/main/java/cn/hiauth/server/config/web/auth/CustomOidcUserInfoMapper.java
  class CustomOidcUserInfoMapper (line 20) | public class CustomOidcUserInfoMapper implements Function<OidcUserInfoAu...
    method CustomOidcUserInfoMapper (line 61) | public CustomOidcUserInfoMapper(CacheUtil cacheUtil, MultiAuthUserServ...
    method getClaimsRequestedByScope (line 66) | private static Map<String, Object> getClaimsRequestedByScope(Map<Strin...
    method apply (line 90) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/config/web/auth/FederatedIdentityIdTokenCustomizer.java
  class FederatedIdentityIdTokenCustomizer (line 14) | public final class FederatedIdentityIdTokenCustomizer implements OAuth2T...
    method customize (line 31) | @Override
    method extractClaims (line 46) | private Map<String, Object> extractClaims(Authentication principal) {

FILE: hiauth-server/src/main/java/cn/hiauth/server/config/web/security/CustomAuthenticationFailureHandler.java
  class CustomAuthenticationFailureHandler (line 18) | public class CustomAuthenticationFailureHandler extends SimpleUrlAuthent...
    method CustomAuthenticationFailureHandler (line 22) | public CustomAuthenticationFailureHandler(String failureUrl) {
    method onAuthenticationFailure (line 30) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/config/web/security/CustomAuthenticationSuccessHandler.java
  class CustomAuthenticationSuccessHandler (line 18) | public class CustomAuthenticationSuccessHandler extends SavedRequestAwar...
    method onAuthenticationSuccess (line 24) | @Override
    method setRequestCache (line 40) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/config/web/security/CustomLoginUrlAuthenticationEntryPoint.java
  class CustomLoginUrlAuthenticationEntryPoint (line 17) | public class CustomLoginUrlAuthenticationEntryPoint extends LoginUrlAuth...
    method CustomLoginUrlAuthenticationEntryPoint (line 19) | public CustomLoginUrlAuthenticationEntryPoint(String loginFormUrl) {
    method determineUrlToUseForThisRequest (line 27) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/config/web/security/MultiAppHttpSessionRequestCache.java
  class MultiAppHttpSessionRequestCache (line 23) | public class MultiAppHttpSessionRequestCache extends HttpSessionRequestC...
    method saveRequest (line 39) | @Override
    method getRequest (line 64) | @Override
    method removeRequest (line 79) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/config/web/security/MultiAuthUserService.java
  class MultiAuthUserService (line 26) | @Service
    method loadUserByUsername (line 53) | public AuthUser loadUserByUsername(String clientId, String username) t...
    method loadUserByPhoneNum (line 62) | public AuthUser loadUserByPhoneNum(String clientId, String phoneNum) {
    method loadUserByUserId (line 71) | public AuthUser loadUserByUserId(String registeredClientId, Long userI...
    method loadAuthUser (line 79) | public AuthUser loadAuthUser(Oauth2RegisteredClient client, User user) {
    method loadUserWeChatCode (line 106) | public AuthUser loadUserWeChatCode(String clientId, String code) {
    method getWechatAccessToken (line 117) | private Map<String, Object> getWechatAccessToken(String code) {
    method getWechatUserInfo (line 125) | private Map<String, Object> getWechatUserInfo(String accessToken, Stri...

FILE: hiauth-server/src/main/java/cn/hiauth/server/config/web/security/account/AccountAuthenticationFilter.java
  class AccountAuthenticationFilter (line 15) | public class AccountAuthenticationFilter extends AbstractAuthenticationP...
    method AccountAuthenticationFilter (line 17) | public AccountAuthenticationFilter(String processUrl) {
    method attemptAuthentication (line 24) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/config/web/security/account/AccountAuthenticationProvider.java
  class AccountAuthenticationProvider (line 28) | @Data
    method authenticate (line 46) | @Override
    method checkPwdLogin (line 90) | private void checkPwdLogin(AuthUser authUser, String password) {
    method checkCaptcha (line 101) | private void checkCaptcha(String formToken, String captcha) {
    method supports (line 114) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/config/web/security/account/AccountAuthenticationToken.java
  class AccountAuthenticationToken (line 8) | public class AccountAuthenticationToken extends AbstractAuthenticationTo...
    method AccountAuthenticationToken (line 17) | public AccountAuthenticationToken(String formToken, String clientId, S...
    method AccountAuthenticationToken (line 27) | public AccountAuthenticationToken(Object principal, Collection<? exten...
    method getCredentials (line 33) | @Override
    method getPrincipal (line 38) | @Override
    method getFormToken (line 43) | public String getFormToken() {
    method getCaptcha (line 47) | public String getCaptcha() {
    method getClientId (line 51) | public String getClientId() {

FILE: hiauth-server/src/main/java/cn/hiauth/server/config/web/security/phone/SmsCodeAuthenticationFilter.java
  class SmsCodeAuthenticationFilter (line 12) | public class SmsCodeAuthenticationFilter extends AbstractAuthenticationP...
    method SmsCodeAuthenticationFilter (line 14) | public SmsCodeAuthenticationFilter(String processUrl) {
    method attemptAuthentication (line 21) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/config/web/security/phone/SmsCodeAuthenticationProvider.java
  class SmsCodeAuthenticationProvider (line 26) | @Data
    method authenticate (line 43) | @Override
    method checkSmsLogin (line 88) | private void checkSmsLogin(String phone, String smsCode) {
    method checkCaptcha (line 100) | private void checkCaptcha(String formToken, String captcha) {
    method supports (line 113) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/config/web/security/phone/SmsCodeAuthenticationToken.java
  class SmsCodeAuthenticationToken (line 8) | public class SmsCodeAuthenticationToken extends AbstractAuthenticationTo...
    method SmsCodeAuthenticationToken (line 17) | public SmsCodeAuthenticationToken(String formToken, String clientId, S...
    method SmsCodeAuthenticationToken (line 27) | public SmsCodeAuthenticationToken(Object principal, Collection<? exten...
    method getCredentials (line 33) | @Override
    method getPrincipal (line 38) | @Override
    method getFormToken (line 43) | public String getFormToken() {
    method getCaptcha (line 47) | public String getCaptcha() {
    method getClientId (line 51) | public String getClientId() {

FILE: hiauth-server/src/main/java/cn/hiauth/server/config/web/security/wechat/QrCodeAuthenticationFilter.java
  class QrCodeAuthenticationFilter (line 10) | public class QrCodeAuthenticationFilter extends AbstractAuthenticationPr...
    method QrCodeAuthenticationFilter (line 12) | public QrCodeAuthenticationFilter(String processUrl) {
    method attemptAuthentication (line 19) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/config/web/security/wechat/QrCodeAuthenticationProvider.java
  class QrCodeAuthenticationProvider (line 22) | @Data
    method authenticate (line 35) | @Override
    method supports (line 75) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/config/web/security/wechat/QrCodeAuthenticationToken.java
  class QrCodeAuthenticationToken (line 8) | public class QrCodeAuthenticationToken extends AbstractAuthenticationTok...
    method QrCodeAuthenticationToken (line 15) | public QrCodeAuthenticationToken(String clientId, String code) {
    method QrCodeAuthenticationToken (line 23) | public QrCodeAuthenticationToken(Object principal, Collection<? extend...
    method getCredentials (line 29) | @Override
    method getPrincipal (line 34) | @Override
    method getClientId (line 39) | public String getClientId() {

FILE: hiauth-server/src/main/java/cn/hiauth/server/controller/AuthConsentController.java
  class AuthConsentController (line 18) | @Controller
    method AuthConsentController (line 24) | public AuthConsentController(RegisteredClientRepository registeredClie...
    method withDescription (line 29) | private static Set<ScopeWithDescription> withDescription(Set<String> s...
    method consent (line 37) | @GetMapping(value = "/oauth2/consent")
    class ScopeWithDescription (line 74) | public static class ScopeWithDescription {
      method ScopeWithDescription (line 90) | ScopeWithDescription(String scope) {

FILE: hiauth-server/src/main/java/cn/hiauth/server/controller/IndexController.java
  class IndexController (line 33) | @Controller
    method index (line 64) | @GetMapping(value = {"/", "/index"})
    method openApp (line 84) | @GetMapping(value = {"/openApp"})
    method profile (line 92) | @GetMapping(value = {"/profile"})
    method setting (line 97) | @GetMapping(value = {"/setting"})
    method me (line 102) | @ResponseBody
    method logout (line 108) | @GetMapping(value = "/logout")
    method me (line 132) | @GetMapping({"/user/me"})
    method myAuthorizationConsentList (line 143) | private List<AuthorizationConsent> myAuthorizationConsentList(String u...

FILE: hiauth-server/src/main/java/cn/hiauth/server/controller/LoginController.java
  class LoginController (line 43) | @Slf4j
    method login (line 76) | @GetMapping(value = {"/login"}, produces = "text/html")
    method image (line 124) | @GetMapping("/auth/code/image")
    method captcha (line 137) | @ResponseBody
    method sms (line 151) | @ResponseBody
    method logoutWithRedirect (line 206) | @GetMapping("/unpapi/logoutWithRedirect")

FILE: hiauth-server/src/main/java/cn/hiauth/server/controller/OauthController.java
  class OauthController (line 25) | @Slf4j
    method updatePwd (line 46) | @PostMapping("/oauth2/user/updatePwd")

FILE: hiauth-server/src/main/java/cn/hiauth/server/controller/TestController.java
  class TestController (line 13) | @Slf4j
    method testException (line 20) | @GetMapping("/unpapi/test/exception")
    method testByZero (line 25) | @GetMapping("/unpapi/test/byZero")
    method testAssert (line 31) | @GetMapping("/unpapi/test/assert")

FILE: hiauth-server/src/main/java/cn/hiauth/server/controller/UnpController.java
  class UnpController (line 26) | @Slf4j
    method info (line 42) | @GetMapping("/info")
    method metadata (line 50) | @PostMapping("/metadata")
    method getImageAsByteArray (line 60) | @GetMapping("/image/{code}")
    method register (line 73) | @PostMapping("/register")

FILE: hiauth-server/src/main/java/cn/hiauth/server/controller/adminspace/CorpMgrController.java
  class CorpMgrController (line 33) | @Slf4j
    method page (line 49) | @PostMapping("/page")
    method findById (line 57) | @PostMapping("/findById")
    method create (line 63) | @PostMapping("/create")
    method update (line 74) | @PostMapping("/update")
    method delete (line 81) | @PostMapping("/delete")
    method listCorp (line 88) | @PostMapping("/listCorp")
    method intoAdminSpace (line 97) | @PostMapping("/intoAdminSpace")
    method intoCorpSpace (line 109) | @PostMapping("/intoCorpSpace")

FILE: hiauth-server/src/main/java/cn/hiauth/server/controller/adminspace/UserMgrController.java
  class UserMgrController (line 25) | @Slf4j
    method page (line 40) | @PostMapping("/page")
    method findById (line 50) | @PostMapping("/findById")
    method create (line 56) | @PostMapping("/create")
    method update (line 64) | @PostMapping("/update")
    method delete (line 71) | @PostMapping("/delete")

FILE: hiauth-server/src/main/java/cn/hiauth/server/controller/common/AppMgrController.java
  class AppMgrController (line 29) | @Slf4j
    method page (line 39) | @PostMapping("/page")
    method findById (line 53) | @PostMapping("/findById")
    method create (line 59) | @PostMapping("/create")
    method update (line 69) | @PostMapping("/update")
    method delete (line 76) | @PostMapping("/delete")
    method limitList (line 83) | @PostMapping("/limitList")

FILE: hiauth-server/src/main/java/cn/hiauth/server/controller/common/AppResourceMgrController.java
  class AppResourceMgrController (line 26) | @Slf4j
    method page (line 36) | @PostMapping("/page")
    method findById (line 44) | @PostMapping("/findById")
    method create (line 50) | @PostMapping("/create")
    method update (line 57) | @PostMapping("/update")
    method delete (line 64) | @PostMapping("/delete")
    method tree (line 71) | @PostMapping("/tree")
    method findAppResourceIdsByRoleAndApp (line 77) | @PostMapping("/findAppResourceIdsByRoleAndApp")

FILE: hiauth-server/src/main/java/cn/hiauth/server/controller/common/CommonController.java
  class CommonController (line 29) | @Slf4j
    method userInfo (line 43) | @PostMapping("/userInfo")
    method codes (line 73) | @PostMapping("/codes")
    method sysMenus (line 79) | @GetMapping("/sysMenus")
    method sysAction (line 106) | @GetMapping("/sysAction")
    method handleFileUpload (line 114) | @PostMapping("/file/uploadImg")

FILE: hiauth-server/src/main/java/cn/hiauth/server/controller/corpspace/AppClientMgrController.java
  class AppClientMgrController (line 34) | @Slf4j
    method page (line 53) | @PostMapping("/page")
    method findById (line 69) | @PostMapping("/findById")
    method add (line 78) | @PostMapping("/add")
    method update (line 100) | @PostMapping("/update")
    method delete (line 112) | @PostMapping("/delete")
    method limitNotHaveApp (line 128) | @PostMapping("/limitNotHaveApp")
    method limitHaveApp (line 137) | @PostMapping("/limitHaveApp")

FILE: hiauth-server/src/main/java/cn/hiauth/server/controller/corpspace/DepMgrController.java
  class DepMgrController (line 29) | @Slf4j
    method page (line 39) | @PostMapping("/page")
    method limit (line 50) | @PostMapping("/limit")
    method findById (line 59) | @PostMapping("/findById")
    method create (line 67) | @PostMapping("/create")
    method update (line 77) | @PostMapping("/update")
    method delete (line 86) | @PostMapping("/delete")
    method depTree (line 95) | @PostMapping("/depTree")

FILE: hiauth-server/src/main/java/cn/hiauth/server/controller/corpspace/DictMgrController.java
  class DictMgrController (line 28) | @Slf4j
    method page (line 38) | @PostMapping("/page")
    method findById (line 51) | @PostMapping("/findById")
    method create (line 59) | @PostMapping("/create")
    method update (line 69) | @PostMapping("/update")
    method delete (line 78) | @PostMapping("/delete")
    method findSubDict (line 89) | @PostMapping("/findSubDict")
    method findDict (line 102) | @PostMapping("/findDict")

FILE: hiauth-server/src/main/java/cn/hiauth/server/controller/corpspace/EmpMgrController.java
  class EmpMgrController (line 35) | @Slf4j
    method page (line 54) | @PostMapping("/page")
    method findById (line 66) | @PostMapping("/findById")
    method create (line 77) | @PostMapping("/create")
    method update (line 87) | @PostMapping("/update")
    method delete (line 96) | @PostMapping("/delete")
    method findUser (line 105) | @PostMapping("/findUser")

FILE: hiauth-server/src/main/java/cn/hiauth/server/controller/corpspace/RoleMgrController.java
  class RoleMgrController (line 25) | @Slf4j
    method page (line 35) | @PostMapping("/page")
    method page (line 47) | @PostMapping("/limit")
    method findById (line 56) | @PostMapping("/findById")
    method create (line 64) | @PostMapping("/create")
    method update (line 74) | @PostMapping("/update")
    method delete (line 83) | @PostMapping("/delete")
    method auth (line 92) | @PostMapping("/auth")

FILE: hiauth-server/src/main/java/cn/hiauth/server/entity/App.java
  class App (line 15) | @Data

FILE: hiauth-server/src/main/java/cn/hiauth/server/entity/AppResource.java
  class AppResource (line 14) | @Data

FILE: hiauth-server/src/main/java/cn/hiauth/server/entity/AuthorizationConsent.java
  class AuthorizationConsent (line 9) | @Data

FILE: hiauth-server/src/main/java/cn/hiauth/server/entity/Corp.java
  class Corp (line 14) | @Data

FILE: hiauth-server/src/main/java/cn/hiauth/server/entity/CorpApp.java
  class CorpApp (line 11) | @Data

FILE: hiauth-server/src/main/java/cn/hiauth/server/entity/CorpAppInfo.java
  class CorpAppInfo (line 6) | @Data

FILE: hiauth-server/src/main/java/cn/hiauth/server/entity/Department.java
  class Department (line 13) | @Data

FILE: hiauth-server/src/main/java/cn/hiauth/server/entity/Dict.java
  class Dict (line 13) | @Data

FILE: hiauth-server/src/main/java/cn/hiauth/server/entity/Employee.java
  class Employee (line 13) | @Data

FILE: hiauth-server/src/main/java/cn/hiauth/server/entity/File.java
  class File (line 11) | @Data

FILE: hiauth-server/src/main/java/cn/hiauth/server/entity/Oauth2Authorization.java
  class Oauth2Authorization (line 13) | @Data

FILE: hiauth-server/src/main/java/cn/hiauth/server/entity/Oauth2AuthorizationConsent.java
  class Oauth2AuthorizationConsent (line 11) | @Data

FILE: hiauth-server/src/main/java/cn/hiauth/server/entity/Oauth2RegisteredClient.java
  class Oauth2RegisteredClient (line 13) | @Data

FILE: hiauth-server/src/main/java/cn/hiauth/server/entity/Role.java
  class Role (line 18) | @Data

FILE: hiauth-server/src/main/java/cn/hiauth/server/entity/RoleAppResource.java
  class RoleAppResource (line 11) | @Data

FILE: hiauth-server/src/main/java/cn/hiauth/server/entity/SysLog.java
  class SysLog (line 13) | @Data

FILE: hiauth-server/src/main/java/cn/hiauth/server/entity/User.java
  class User (line 15) | @Data

FILE: hiauth-server/src/main/java/cn/hiauth/server/mapper/AppMapper.java
  type AppMapper (line 16) | @Mapper
    method findByCid (line 19) | @Select("""
    method limitNotHaveApp (line 26) | @Select("""
    method limitHaveApp (line 37) | @Select("""
    method findByClientId (line 45) | @ResultMap("BaseResultMap")

FILE: hiauth-server/src/main/java/cn/hiauth/server/mapper/AppResourceMapper.java
  type AppResourceMapper (line 15) | @Mapper
    method findByAppIdAndRoleIds (line 18) | @Select("""

FILE: hiauth-server/src/main/java/cn/hiauth/server/mapper/CorpAppMapper.java
  type CorpAppMapper (line 15) | @Mapper
    method limitCorpAppInfoByUserId (line 18) | @Select("""

FILE: hiauth-server/src/main/java/cn/hiauth/server/mapper/CorpMapper.java
  type CorpMapper (line 15) | @Mapper
    method findByUserId (line 18) | @ResultMap("BaseResultMap")

FILE: hiauth-server/src/main/java/cn/hiauth/server/mapper/DepartmentMapper.java
  type DepartmentMapper (line 14) | @Mapper
    method findDepIdsByEmpId (line 17) | @Select("""
    method addDepEmp (line 23) | @Insert("""
    method modifyDepEmp (line 33) | @Insert("""
    method resetEmpDep (line 44) | @Delete("""
    method del (line 52) | @Delete("""

FILE: hiauth-server/src/main/java/cn/hiauth/server/mapper/DictMapper.java
  type DictMapper (line 15) | @Mapper
    method pageByPcode (line 19) | @ResultMap("BaseResultMap")
    method childCount (line 30) | @Select("""

FILE: hiauth-server/src/main/java/cn/hiauth/server/mapper/EmployeeMapper.java
  type EmployeeMapper (line 17) | @Mapper
    method pageByDepId (line 20) | @Select("""
    method findOneByAppIdAndUserId (line 34) | @ResultMap("BaseResultMap")

FILE: hiauth-server/src/main/java/cn/hiauth/server/mapper/FileMapper.java
  type FileMapper (line 12) | @Mapper

FILE: hiauth-server/src/main/java/cn/hiauth/server/mapper/Oauth2AuthorizationConsentMapper.java
  type Oauth2AuthorizationConsentMapper (line 10) | @Mapper

FILE: hiauth-server/src/main/java/cn/hiauth/server/mapper/Oauth2AuthorizationMapper.java
  type Oauth2AuthorizationMapper (line 10) | @Mapper

FILE: hiauth-server/src/main/java/cn/hiauth/server/mapper/Oauth2RegisteredClientMapper.java
  type Oauth2RegisteredClientMapper (line 15) | @Mapper
    method findByClientId (line 18) | @Select("SELECT DISTINCT O.* FROM oauth2_registered_client O WHERE O.c...
    method pageByCorpId (line 21) | @ResultMap("BaseResultMap")

FILE: hiauth-server/src/main/java/cn/hiauth/server/mapper/RoleAppResourceMapper.java
  type RoleAppResourceMapper (line 14) | @Mapper
    method auth (line 17) | @Select("""

FILE: hiauth-server/src/main/java/cn/hiauth/server/mapper/RoleMapper.java
  type RoleMapper (line 14) | @Mapper
    method findByEmpId (line 17) | @ResultMap("BaseResultMap")
    method removeEmpRole (line 26) | @Delete("""
    method createEmpRole (line 39) | @Insert("""

FILE: hiauth-server/src/main/java/cn/hiauth/server/mapper/SysLogMapper.java
  type SysLogMapper (line 10) | @Mapper

FILE: hiauth-server/src/main/java/cn/hiauth/server/mapper/UserMapper.java
  type UserMapper (line 10) | @Mapper

FILE: hiauth-server/src/main/java/cn/hiauth/server/service/AppResourceService.java
  type AppResourceService (line 14) | public interface AppResourceService extends IService<AppResource> {
    method findByAppIdAndRoleIds (line 16) | List<AppResource> findByAppIdAndRoleIds(Long appId, Set<Long> roleIds);
    method findAppResourceTree (line 18) | List<CommonTreeNodeVo> findAppResourceTree(Long appId);
    method findAppResourceIdsByRoleAndApp (line 20) | Set<Long> findAppResourceIdsByRoleAndApp(FindAppResourceIdsByRoleAndAp...

FILE: hiauth-server/src/main/java/cn/hiauth/server/service/AppService.java
  type AppService (line 14) | public interface AppService extends IService<App> {
    method limitNotHaveApp (line 16) | List<App> limitNotHaveApp(AppClientLimitDto dto);
    method limitHaveApp (line 18) | List<App> limitHaveApp(AppClientLimitDto dto);
    method findByIds (line 20) | Map<Long, App> findByIds(Set<Long> appIds);

FILE: hiauth-server/src/main/java/cn/hiauth/server/service/CorpAppService.java
  type CorpAppService (line 6) | public interface CorpAppService extends IService<CorpApp> {

FILE: hiauth-server/src/main/java/cn/hiauth/server/service/CorpService.java
  type CorpService (line 15) | public interface CorpService extends IService<Corp> {
    method findCorpAppResourceTree (line 17) | List<CorpResourceTreeNodeVo> findCorpAppResourceTree(Long cid);
    method register (line 19) | void register(RegisterDto dto);
    method findIndexCorpAppByUserId (line 21) | List<IndexCorpAppVo> findIndexCorpAppByUserId(Long userId, Long appId);
    method saveCorpAppBatch (line 23) | void saveCorpAppBatch(Long cid, Set<Long> appIds);

FILE: hiauth-server/src/main/java/cn/hiauth/server/service/DepartmentService.java
  type DepartmentService (line 13) | public interface DepartmentService extends IService<Department> {
    method findDepTree (line 15) | List<CommonTreeNodeVo> findDepTree(Long cid);
    method findDepIdsByEmpId (line 17) | Set<Long> findDepIdsByEmpId(Long cid, Long empId);

FILE: hiauth-server/src/main/java/cn/hiauth/server/service/DictService.java
  type DictService (line 14) | public interface DictService extends IService<Dict> {
    method pageByPcode (line 16) | IPage<Dict> pageByPcode(Page<Dict> p, LambdaQueryWrapper<Dict> queryWa...
    method childCount (line 18) | int childCount(Set<Long> ids);

FILE: hiauth-server/src/main/java/cn/hiauth/server/service/EmployeeService.java
  type EmployeeService (line 17) | public interface EmployeeService extends IService<Employee> {
    method pageByDepId (line 19) | IPage<Employee> pageByDepId(Page<Employee> p, LambdaQueryWrapper<Emplo...
    method lastLoginCorpAdminByUserId (line 21) | Employee lastLoginCorpAdminByUserId(Long userId);
    method create (line 23) | EmpVo create(EmpCreateDto dto);
    method modify (line 25) | EmpVo modify(Long cid, EmpUpdateDto dto);
    method del (line 27) | boolean del(Long cid, Set<Long> ids);
    method swichCorp (line 29) | void swichCorp(Long userId, Long cid);

FILE: hiauth-server/src/main/java/cn/hiauth/server/service/FileService.java
  type FileService (line 9) | public interface FileService extends IService<File> {

FILE: hiauth-server/src/main/java/cn/hiauth/server/service/Oauth2AuthorizationConsentService.java
  type Oauth2AuthorizationConsentService (line 9) | public interface Oauth2AuthorizationConsentService extends IService<Oaut...

FILE: hiauth-server/src/main/java/cn/hiauth/server/service/Oauth2AuthorizationService.java
  type Oauth2AuthorizationService (line 9) | public interface Oauth2AuthorizationService extends IService<Oauth2Autho...

FILE: hiauth-server/src/main/java/cn/hiauth/server/service/Oauth2RegisteredClientService.java
  type Oauth2RegisteredClientService (line 12) | public interface Oauth2RegisteredClientService extends IService<Oauth2Re...
    method findByClientId (line 14) | Oauth2RegisteredClient findByClientId(String clientId);
    method pageByCorpId (line 16) | IPage<Oauth2RegisteredClient> pageByCorpId(Page<Oauth2RegisteredClient...

FILE: hiauth-server/src/main/java/cn/hiauth/server/service/RoleService.java
  type RoleService (line 13) | public interface RoleService extends IService<Role> {
    method findByEmpId (line 15) | List<Role> findByEmpId(Long empId);
    method setEmpRole (line 17) | void setEmpRole(Long cid, Long empId, Set<Long> roleIds);
    method auth (line 19) | Boolean auth(RoleAuthDto dto);

FILE: hiauth-server/src/main/java/cn/hiauth/server/service/SimpleSecurityService.java
  class SimpleSecurityService (line 24) | @Slf4j
    method loadSecurityUser (line 40) | @Override
    method loadSecurityUser (line 47) | @Override
    method sendSmsCode (line 53) | @Override
    method loadUserCorps (line 59) | @Override
    method switchCorp (line 66) | @Override
    method convert (line 85) | private MySecurityUser convert(User user) {

FILE: hiauth-server/src/main/java/cn/hiauth/server/service/SysLogService.java
  type SysLogService (line 9) | public interface SysLogService extends IService<SysLog> {

FILE: hiauth-server/src/main/java/cn/hiauth/server/service/UserService.java
  type UserService (line 9) | public interface UserService extends IService<User> {

FILE: hiauth-server/src/main/java/cn/hiauth/server/service/impl/AppResourceServiceImpl.java
  class AppResourceServiceImpl (line 22) | @Service
    method buildDepTree (line 34) | private static List<CommonTreeNodeVo> buildDepTree(List<AppResource> l...
    method buildChild (line 47) | private static void buildChild(CommonTreeNodeVo parent, List<AppResour...
    method findByAppIdAndRoleIds (line 60) | @Override
    method findAppResourceTree (line 65) | @Override
    method findAppResourceIdsByRoleAndApp (line 75) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/service/impl/AppServiceImpl.java
  class AppServiceImpl (line 19) | @Service
    method limitNotHaveApp (line 22) | @Override
    method limitHaveApp (line 27) | @Override
    method findByIds (line 32) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/service/impl/CorpAppServiceImpl.java
  class CorpAppServiceImpl (line 9) | @Service

FILE: hiauth-server/src/main/java/cn/hiauth/server/service/impl/CorpServiceImpl.java
  class CorpServiceImpl (line 28) | @Service
    method buildTree (line 55) | private static void buildTree(CorpResourceTreeNodeVo parent, List<AppR...
    method buildChild (line 65) | private static void buildChild(CorpResourceTreeNodeVo parent, List<App...
    method findCorpAppResourceTree (line 80) | @Override
    method register (line 104) | @Override
    method findIndexCorpAppByUserId (line 136) | @Override
    method saveCorpAppBatch (line 142) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/service/impl/DepartmentServiceImpl.java
  class DepartmentServiceImpl (line 21) | @Service
    method buildDepTree (line 24) | private static List<CommonTreeNodeVo> buildDepTree(List<Department> li...
    method buildChild (line 37) | private static void buildChild(CommonTreeNodeVo parent, List<Departmen...
    method findDepIdsByEmpId (line 50) | @Override
    method findDepTree (line 55) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/service/impl/DictServiceImpl.java
  class DictServiceImpl (line 17) | @Service
    method pageByPcode (line 20) | @Override
    method childCount (line 25) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/service/impl/EmployeeServiceImpl.java
  class EmployeeServiceImpl (line 28) | @Service
    method pageByDepId (line 40) | @Override
    method lastLoginCorpAdminByUserId (line 45) | @Override
    method create (line 57) | @Override
    method modify (line 79) | @Override
    method del (line 100) | @Override
    method swichCorp (line 107) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/service/impl/FileServiceImpl.java
  class FileServiceImpl (line 12) | @Service

FILE: hiauth-server/src/main/java/cn/hiauth/server/service/impl/Oauth2AuthorizationConsentServiceImpl.java
  class Oauth2AuthorizationConsentServiceImpl (line 12) | @Service

FILE: hiauth-server/src/main/java/cn/hiauth/server/service/impl/Oauth2AuthorizationServiceImpl.java
  class Oauth2AuthorizationServiceImpl (line 12) | @Service

FILE: hiauth-server/src/main/java/cn/hiauth/server/service/impl/Oauth2RegisteredClientServiceImpl.java
  class Oauth2RegisteredClientServiceImpl (line 15) | @Service
    method findByClientId (line 18) | @Override
    method pageByCorpId (line 23) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/service/impl/RoleServiceImpl.java
  class RoleServiceImpl (line 23) | @Service
    method findByEmpId (line 34) | @Override
    method setEmpRole (line 39) | @Override
    method auth (line 56) | @Override

FILE: hiauth-server/src/main/java/cn/hiauth/server/service/impl/SysLogServiceImpl.java
  class SysLogServiceImpl (line 12) | @Service

FILE: hiauth-server/src/main/java/cn/hiauth/server/service/impl/UserServiceImpl.java
  class UserServiceImpl (line 12) | @Service

FILE: hiauth-server/src/main/java/cn/hiauth/server/utils/AliyunSmsUtils.java
  class AliyunSmsUtils (line 17) | @Slf4j
    method AliyunSmsUtils (line 24) | private AliyunSmsUtils() {
    method AliyunSmsUtils (line 27) | public AliyunSmsUtils(String accessKeyId, String accessKeySecret, Stri...
    method main (line 38) | public static void main(String[] args) throws Exception {
    method sendSms (line 69) | public void sendSms(String phoneNumbers, String templateCode, Map<Stri...
    method sendSms (line 80) | public void sendSms(String phoneNumbers, String signName, String templ...
    method createSmsTemplate (line 103) | private CreateSmsTemplateResponse createSmsTemplate(String signName, I...
    method sendVerificationCode (line 129) | private void sendVerificationCode(String phone, String code) throws Ex...
    method testSendSmsVerify (line 140) | private void testSendSmsVerify() throws Exception {

FILE: hiauth-server/src/main/java/cn/hiauth/server/utils/AppResourceUtils.java
  class AppResourceUtils (line 9) | public class AppResourceUtils {
    method sort (line 11) | public static List<AppResource> sort(List<AppResource> datas) {
    method getChild (line 28) | private static List<AppResource> getChild(AppResource node, List<AppRe...

FILE: hiauth-server/src/main/java/cn/hiauth/server/utils/Constant.java
  class Constant (line 3) | public class Constant {

FILE: hiauth-server/src/main/java/cn/hiauth/server/utils/DateTimeUtils.java
  class DateTimeUtils (line 6) | public class DateTimeUtils {
    method format (line 10) | public static String format(LocalDateTime time) {

FILE: hiauth-server/src/main/java/cn/hiauth/server/utils/DepartmentUtils.java
  class DepartmentUtils (line 9) | public class DepartmentUtils {
    method sort (line 11) | public static List<Department> sort(List<Department> deps) {
    method getChild (line 28) | private static List<Department> getChild(Department dep, List<Departme...

FILE: hiauth-server/src/main/java/cn/hiauth/server/utils/Oauth2RegisteredClientUtils.java
  class Oauth2RegisteredClientUtils (line 8) | public class Oauth2RegisteredClientUtils {
    method getDefaultClient (line 19) | public static Oauth2RegisteredClient getDefaultClient(Long cid, Long a...
    method getClientSettings (line 41) | public static String getClientSettings(Long cid, Long appId) {
    method getTokenSettings (line 45) | public static String getTokenSettings(Integer accessTokenTimeToLive) {

FILE: hiauth-server/src/main/java/cn/hiauth/server/utils/RsaUtils.java
  class RsaUtils (line 15) | @Slf4j
    method encrypt (line 39) | public static String encrypt(String content, PublicKey publicKey) {
    method encrypt (line 55) | public static String encrypt(String content, String publicKey) {
    method decrypt (line 72) | public static String decrypt(String content, PrivateKey privateKey) {
    method decrypt (line 88) | public static String decrypt(String content, String privateKey) {
    method generateKeyPair (line 101) | public static Map<String, String> generateKeyPair() {
    method main (line 126) | public static void main(String[] args) {

FILE: hiauth-server/src/main/java/cn/hiauth/server/utils/SmsUtils.java
  type SmsUtils (line 5) | public interface SmsUtils {
    method sendSms (line 7) | void sendSms(String phoneNumbers, String templateCode, Map<String, Str...

FILE: hiauth-server/src/main/java/cn/hiauth/server/utils/jose/Jwks.java
  class Jwks (line 35) | public final class Jwks {
    method Jwks (line 37) | private Jwks() {
    method generateRsa (line 40) | public static RSAKey generateRsa() {
    method generateEc (line 50) | public static ECKey generateEc() {
    method generateSecret (line 61) | public static OctetSequenceKey generateSecret() {

FILE: hiauth-server/src/main/java/cn/hiauth/server/utils/jose/KeyGeneratorUtils.java
  class KeyGeneratorUtils (line 32) | final class KeyGeneratorUtils {
    method KeyGeneratorUtils (line 34) | private KeyGeneratorUtils() {
    method generateSecretKey (line 37) | static SecretKey generateSecretKey() {
    method generateRsaKey (line 47) | static KeyPair generateRsaKey() {
    method generateEcKey (line 59) | static KeyPair generateEcKey() {

FILE: hiauth-server/src/main/resources/static/bootstrap-5.3.0/js/bootstrap.bundle.min.js
  function T (line 6) | function T(t,e){return e&&`${e}::${w++}`||t.uidEvent||w++}
  function C (line 6) | function C(t){const e=T(t);return t.uidEvent=e,y[e]=y[e]||{},y[e]}
  function O (line 6) | function O(t,e,i=null){return Object.values(t).find((t=>t.callable===e&&...
  function x (line 6) | function x(t,e,i){const n="string"==typeof e,s=n?i:e||i;let o=D(t);retur...
  function k (line 6) | function k(t,e,i,n,s){if("string"!=typeof e||!t)return;let[o,r,a]=x(e,i,...
  function L (line 6) | function L(t,e,i,n,s){const o=O(e[i],n,s);o&&(t.removeEventListener(i,o,...
  function S (line 6) | function S(t,e,i,n){const s=e[i]||{};for(const[o,r]of Object.entries(s))...
  function D (line 6) | function D(t){return t=t.replace(b,""),A[t]||t}
  method on (line 6) | on(t,e,i,n){k(t,e,i,n,!1)}
  method one (line 6) | one(t,e,i,n){k(t,e,i,n,!0)}
  method off (line 6) | off(t,e,i,n){if("string"!=typeof e||!t)return;const[s,o,r]=x(e,i,n),a=r!...
  method trigger (line 6) | trigger(t,e,i){if("string"!=typeof e||!t)return null;const n=h();let s=n...
  function N (line 6) | function N(t,e={}){for(const[i,n]of Object.entries(e))try{t[i]=n}catch(e...
  method set (line 6) | set(t,e,i){P.has(t)||P.set(t,new Map);const n=P.get(t);n.has(e)||0===n.s...
  method remove (line 6) | remove(t,e){if(!P.has(t))return;const i=P.get(t);i.delete(e),0===i.size&...
  function M (line 6) | function M(t){if("true"===t)return!0;if("false"===t)return!1;if(t===Numb...
  function F (line 6) | function F(t){return t.replace(/[A-Z]/g,(t=>`-${t.toLowerCase()}`))}
  method setDataAttribute (line 6) | setDataAttribute(t,e,i){t.setAttribute(`data-bs-${F(e)}`,i)}
  method removeDataAttribute (line 6) | removeDataAttribute(t,e){t.removeAttribute(`data-bs-${F(e)}`)}
  method getDataAttributes (line 6) | getDataAttributes(t){if(!t)return{};const e={},i=Object.keys(t.dataset)....
  class $ (line 6) | class ${static get Default(){return{}}static get DefaultType(){return{}}...
    method Default (line 6) | static get Default(){return{}}
    method DefaultType (line 6) | static get DefaultType(){return{}}
    method NAME (line 6) | static get NAME(){throw new Error('You have to implement the static me...
    method _getConfig (line 6) | _getConfig(t){return t=this._mergeConfigObj(t),t=this._configAfterMerg...
    method _configAfterMerge (line 6) | _configAfterMerge(t){return t}
    method _mergeConfigObj (line 6) | _mergeConfigObj(t,e){const i=n(e)?H.getDataAttribute(e,"config"):{};re...
    method _typeCheckConfig (line 6) | _typeCheckConfig(t,e=this.constructor.DefaultType){for(const[s,o]of Ob...
  class W (line 6) | class W extends ${constructor(t,e){super(),(t=s(t))&&(this._element=t,th...
    method constructor (line 6) | constructor(t,e){super(),(t=s(t))&&(this._element=t,this._config=this....
    method dispose (line 6) | dispose(){j.remove(this._element,this.constructor.DATA_KEY),I.off(this...
    method _queueCallback (line 6) | _queueCallback(t,e,i=!0){m(t,e,i)}
    method _getConfig (line 6) | _getConfig(t){return t=this._mergeConfigObj(t,this._element),t=this._c...
    method getInstance (line 6) | static getInstance(t){return j.get(s(t),this.DATA_KEY)}
    method getOrCreateInstance (line 6) | static getOrCreateInstance(t,e={}){return this.getInstance(t)||new thi...
    method VERSION (line 6) | static get VERSION(){return"5.3.0-alpha1"}
    method DATA_KEY (line 6) | static get DATA_KEY(){return`bs.${this.NAME}`}
    method EVENT_KEY (line 6) | static get EVENT_KEY(){return`.${this.DATA_KEY}`}
    method eventName (line 6) | static eventName(t){return`${t}${this.EVENT_KEY}`}
  method parents (line 6) | parents(t,e){const i=[];let n=t.parentNode.closest(e);for(;n;)i.push(n),...
  method prev (line 6) | prev(t,e){let i=t.previousElementSibling;for(;i;){if(i.matches(e))return...
  method next (line 6) | next(t,e){let i=t.nextElementSibling;for(;i;){if(i.matches(e))return[i];...
  method focusableChildren (line 6) | focusableChildren(t){const e=["a","button","input","textarea","select","...
  method getSelectorFromElement (line 6) | getSelectorFromElement(t){const e=B(t);return e&&z.findOne(e)?e:null}
  method getElementFromSelector (line 6) | getElementFromSelector(t){const e=B(t);return e?z.findOne(e):null}
  method getMultipleElementsFromSelector (line 6) | getMultipleElementsFromSelector(t){const e=B(t);return e?z.find(e):[]}
  class q (line 6) | class q extends W{static get NAME(){return"alert"}close(){if(I.trigger(t...
    method NAME (line 6) | static get NAME(){return"alert"}
    method close (line 6) | close(){if(I.trigger(this._element,"close.bs.alert").defaultPrevented)...
    method _destroyElement (line 6) | _destroyElement(){this._element.remove(),I.trigger(this._element,"clos...
    method jQueryInterface (line 6) | static jQueryInterface(t){return this.each((function(){const e=q.getOr...
  class K (line 6) | class K extends W{static get NAME(){return"button"}toggle(){this._elemen...
    method NAME (line 6) | static get NAME(){return"button"}
    method toggle (line 6) | toggle(){this._element.setAttribute("aria-pressed",this._element.class...
    method jQueryInterface (line 6) | static jQueryInterface(t){return this.each((function(){const e=K.getOr...
  class Y (line 6) | class Y extends ${constructor(t,e){super(),this._element=t,t&&Y.isSuppor...
    method constructor (line 6) | constructor(t,e){super(),this._element=t,t&&Y.isSupported()&&(this._co...
    method Default (line 6) | static get Default(){return Q}
    method DefaultType (line 6) | static get DefaultType(){return X}
    method NAME (line 6) | static get NAME(){return"swipe"}
    method dispose (line 6) | dispose(){I.off(this._element,".bs.swipe")}
    method _start (line 6) | _start(t){this._supportPointerEvents?this._eventIsPointerPenTouch(t)&&...
    method _end (line 6) | _end(t){this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX-this....
    method _move (line 6) | _move(t){this._deltaX=t.touches&&t.touches.length>1?0:t.touches[0].cli...
    method _handleSwipe (line 6) | _handleSwipe(){const t=Math.abs(this._deltaX);if(t<=40)return;const e=...
    method _initEvents (line 6) | _initEvents(){this._supportPointerEvents?(I.on(this._element,"pointerd...
    method _eventIsPointerPenTouch (line 6) | _eventIsPointerPenTouch(t){return this._supportPointerEvents&&("pen"==...
    method isSupported (line 6) | static isSupported(){return"ontouchstart"in document.documentElement||...
  class rt (line 6) | class rt extends W{constructor(t,e){super(t,e),this._interval=null,this....
    method constructor (line 6) | constructor(t,e){super(t,e),this._interval=null,this._activeElement=nu...
    method Default (line 6) | static get Default(){return st}
    method DefaultType (line 6) | static get DefaultType(){return ot}
    method NAME (line 6) | static get NAME(){return"carousel"}
    method next (line 6) | next(){this._slide(U)}
    method nextWhenVisible (line 6) | nextWhenVisible(){!document.hidden&&o(this._element)&&this.next()}
    method prev (line 6) | prev(){this._slide(G)}
    method pause (line 6) | pause(){this._isSliding&&i(this._element),this._clearInterval()}
    method cycle (line 6) | cycle(){this._clearInterval(),this._updateInterval(),this._interval=se...
    method _maybeEnableCycle (line 6) | _maybeEnableCycle(){this._config.ride&&(this._isSliding?I.one(this._el...
    method to (line 6) | to(t){const e=this._getItems();if(t>e.length-1||t<0)return;if(this._is...
    method dispose (line 6) | dispose(){this._swipeHelper&&this._swipeHelper.dispose(),super.dispose()}
    method _configAfterMerge (line 6) | _configAfterMerge(t){return t.defaultInterval=t.interval,t}
    method _addEventListeners (line 6) | _addEventListeners(){this._config.keyboard&&I.on(this._element,"keydow...
    method _addTouchEventListeners (line 6) | _addTouchEventListeners(){for(const t of z.find(".carousel-item img",t...
    method _keydown (line 6) | _keydown(t){if(/input|textarea/i.test(t.target.tagName))return;const e...
    method _getItemIndex (line 6) | _getItemIndex(t){return this._getItems().indexOf(t)}
    method _setActiveIndicatorElement (line 6) | _setActiveIndicatorElement(t){if(!this._indicatorsElement)return;const...
    method _updateInterval (line 6) | _updateInterval(){const t=this._activeElement||this._getActive();if(!t...
    method _slide (line 6) | _slide(t,e=null){if(this._isSliding)return;const i=this._getActive(),n...
    method _isAnimated (line 6) | _isAnimated(){return this._element.classList.contains("slide")}
    method _getActive (line 6) | _getActive(){return z.findOne(".active.carousel-item",this._element)}
    method _getItems (line 6) | _getItems(){return z.find(".carousel-item",this._element)}
    method _clearInterval (line 6) | _clearInterval(){this._interval&&(clearInterval(this._interval),this._...
    method _directionToOrder (line 6) | _directionToOrder(t){return u()?t===J?G:U:t===J?U:G}
    method _orderToDirection (line 6) | _orderToDirection(t){return u()?t===G?J:Z:t===G?Z:J}
    method jQueryInterface (line 6) | static jQueryInterface(t){return this.each((function(){const e=rt.getO...
  class ft (line 6) | class ft extends W{constructor(t,e){super(t,e),this._isTransitioning=!1,...
    method constructor (line 6) | constructor(t,e){super(t,e),this._isTransitioning=!1,this._triggerArra...
    method Default (line 6) | static get Default(){return dt}
    method DefaultType (line 6) | static get DefaultType(){return ut}
    method NAME (line 6) | static get NAME(){return"collapse"}
    method toggle (line 6) | toggle(){this._isShown()?this.hide():this.show()}
    method show (line 6) | show(){if(this._isTransitioning||this._isShown())return;let t=[];if(th...
    method hide (line 6) | hide(){if(this._isTransitioning||!this._isShown())return;if(I.trigger(...
    method _isShown (line 6) | _isShown(t=this._element){return t.classList.contains(at)}
    method _configAfterMerge (line 6) | _configAfterMerge(t){return t.toggle=Boolean(t.toggle),t.parent=s(t.pa...
    method _getDimension (line 6) | _getDimension(){return this._element.classList.contains("collapse-hori...
    method _initializeChildren (line 6) | _initializeChildren(){if(!this._config.parent)return;const t=this._get...
    method _getFirstLevelChildren (line 6) | _getFirstLevelChildren(t){const e=z.find(":scope .collapse .collapse",...
    method _addAriaAndCollapsedClass (line 6) | _addAriaAndCollapsedClass(t,e){if(t.length)for(const i of t)i.classLis...
    method jQueryInterface (line 6) | static jQueryInterface(t){const e={};return"string"==typeof t&&/show|h...
  function Ht (line 6) | function Ht(t){return t?(t.nodeName||"").toLowerCase():null}
  function $t (line 6) | function $t(t){if(null==t)return window;if("[object Window]"!==t.toStrin...
  function Wt (line 6) | function Wt(t){return t instanceof $t(t).Element||t instanceof Element}
  function Bt (line 6) | function Bt(t){return t instanceof $t(t).HTMLElement||t instanceof HTMLE...
  function zt (line 6) | function zt(t){return"undefined"!=typeof ShadowRoot&&(t instanceof $t(t)...
  function qt (line 6) | function qt(t){return t.split("-")[0]}
  function Xt (line 6) | function Xt(){va
Condensed preview — 2040 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (7,191K chars).
[
  {
    "path": ".github/workflows/deploy.yml",
    "chars": 1458,
    "preview": "name: Deploy Docs Pages\n\non:\n  push:\n    #分支名字\n    branches: [master]\n\n# 设置tokenn访问权限\npermissions:\n  contents: read\n  pa"
  },
  {
    "path": ".gitignore",
    "chars": 604,
    "preview": "HELP.md\ntarget/\ntarget/*\n!.mvn/wrapper/maven-wrapper.jar\n!**/src/main/**\n!**/src/test/**\n*.pdf\n\n### STS ###\n.apt_generat"
  },
  {
    "path": "LICENSE",
    "chars": 1079,
    "preview": " \nMIT License (MIT)\n\nCopyright © 2025 HiAuth\n\nPermission is hereby granted, free of charge, to any person obtaining a co"
  },
  {
    "path": "README.md",
    "chars": 7649,
    "preview": "<h1 align=\"center\">Hi Auth</h1>\n\n<div align=\"center\">\n\nHiAuth是一个开源的基于OAuth2.0协议的认证、授权系统,除了标准的OAuth2.0授权流程功能外,还提供了应用管理、用户"
  },
  {
    "path": "cicd/Dockerfile",
    "chars": 906,
    "preview": "FROM ubuntu:jdk21-ng-24\n\n# 设置语言\nENV LANG en_US.UTF-8\nENV LANG C.UTF-8\nENV LC_ALL C.UTF-8\n\n# 设置地理位置\nENV TZ=Asia/Shanghai\n"
  },
  {
    "path": "cicd/Jenkinsfile",
    "chars": 1558,
    "preview": "pipeline {\n\n    agent any\n\n    // 设置环境变量\n    environment {\n        BUILD_VERSION = sh(script: 'git rev-parse --short HEA"
  },
  {
    "path": "cicd/hiauth.properties",
    "chars": 1326,
    "preview": "\n# login page title, default:\nloginPage.title=\\u7edf\\u4e00\\u8ba4\\u8bc1\\u4e2d\\u5fc3\n# login page static file name\nloginPa"
  },
  {
    "path": "cicd/nginx.conf",
    "chars": 1766,
    "preview": "worker_processes auto;\npid /run/nginx.pid;\ninclude /etc/nginx/modules-enabled/*.conf;\n\nevents {\n    worker_connections 7"
  },
  {
    "path": "docs/.postcssrc.json",
    "chars": 140,
    "preview": "{\n  \"plugins\": {\n    \"postcss-rtlcss\": {\n      \"ltrPrefix\": \":where([dir=\\\"ltr\\\"])\",\n      \"rtlPrefix\": \":where([dir=\\\"r"
  },
  {
    "path": "docs/.vitepress/config/en.ts",
    "chars": 2743,
    "preview": "import { createRequire } from 'module'\nimport { defineConfig, type DefaultTheme } from 'vitepress'\n\nconst require = crea"
  },
  {
    "path": "docs/.vitepress/config/index.ts",
    "chars": 263,
    "preview": "import { defineConfig } from 'vitepress'\nimport { shared } from './shared'\nimport { en } from './en'\nimport { zh } from "
  },
  {
    "path": "docs/.vitepress/config/shared.ts",
    "chars": 3128,
    "preview": "import {defineConfig} from 'vitepress'\nimport {groupIconMdPlugin, groupIconVitePlugin, localIconLoader} from 'vitepress-"
  },
  {
    "path": "docs/.vitepress/config/zh.ts",
    "chars": 4109,
    "preview": "import { createRequire } from 'module'\nimport { defineConfig, type DefaultTheme } from 'vitepress'\n\nconst require = crea"
  },
  {
    "path": "docs/.vitepress/theme/index.ts",
    "chars": 113,
    "preview": "import Theme from 'vitepress/theme'\nimport 'virtual:group-icons.css'\nimport './styles.css'\n\nexport default Theme\n"
  },
  {
    "path": "docs/.vitepress/theme/styles.css",
    "chars": 952,
    "preview": "@import url('https://fonts.googleapis.com/css2?family=Vazirmatn:wght@100..900&display=swap');\n\n:root:where(:lang(fa)) {\n"
  },
  {
    "path": "docs/en/guide/about-topic.md",
    "chars": 7,
    "preview": "edit..."
  },
  {
    "path": "docs/en/guide/backend.md",
    "chars": 7,
    "preview": "edit..."
  },
  {
    "path": "docs/en/guide/docker.md",
    "chars": 5725,
    "preview": "# Docker Edition {#docker}\n\nThe integration process for the Docker edition is similar to the SaaS edition, except that b"
  },
  {
    "path": "docs/en/guide/frontend.md",
    "chars": 7,
    "preview": "edit..."
  },
  {
    "path": "docs/en/guide/hiauth-client.md",
    "chars": 7,
    "preview": "edit..."
  },
  {
    "path": "docs/en/guide/issue.md",
    "chars": 7,
    "preview": "edit..."
  },
  {
    "path": "docs/en/guide/k8s.md",
    "chars": 7,
    "preview": "edit..."
  },
  {
    "path": "docs/en/guide/quick-start.md",
    "chars": 869,
    "preview": "# Quick Start {#quick-start}\n\n## Admin Console {#admin}\n\nExperience it on the [Admin End](http://auth.hiauth.cn/admin).\n"
  },
  {
    "path": "docs/en/guide/saas.md",
    "chars": 7396,
    "preview": "# SaaS Edition {#saas}\n\nTo integrate the SaaS edition, users need to sign up for an account on HiAuth, add applications,"
  },
  {
    "path": "docs/en/guide/sourcecode.md",
    "chars": 3587,
    "preview": "# Source Code Edition {#sourcecode}\nThe integration process for the source code edition is similar to the Docker edition"
  },
  {
    "path": "docs/en/guide/test.md",
    "chars": 7,
    "preview": "edit..."
  },
  {
    "path": "docs/en/guide/what-is-hiauth.md",
    "chars": 4112,
    "preview": "# What is HiAuth? {#what-is-hiauth}\n\nHiAuth is an authentication and authorization system based on the OAuth2.0 protocol"
  },
  {
    "path": "docs/en/index.md",
    "chars": 1459,
    "preview": "---\nlayout: home\n\ntitle: HiAuth\ntitleTemplate: Authentication and Authorization Service Based on OAuth2.0 Protocol\n\nhero"
  },
  {
    "path": "docs/lunaria.config.json",
    "chars": 639,
    "preview": "{\n  \"$schema\": \"./node_modules/@lunariajs/core/config.schema.json\",\n  \"repository\": {\n    \"name\": \"bestaone/HiAuth\",\n   "
  },
  {
    "path": "docs/package.json",
    "chars": 544,
    "preview": "{\n  \"name\": \"docs\",\n  \"version\": \"3.0.0\",\n  \"private\": true,\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"vitepress de"
  },
  {
    "path": "docs/public/pure.html",
    "chars": 331,
    "preview": "<!doctype html>\n<html>\n  <head>\n    <title>Plain HTML page | VitePress</title>\n    <meta charset=\"utf-8\" />\n    <meta na"
  },
  {
    "path": "docs/zh/guide/about-topic.md",
    "chars": 6,
    "preview": "编辑中..."
  },
  {
    "path": "docs/zh/guide/backend.md",
    "chars": 7,
    "preview": "编辑中...\n"
  },
  {
    "path": "docs/zh/guide/docker.md",
    "chars": 4462,
    "preview": "# Docker版 {#docker}\nDocker版的集成过程和SaaS版类似,只不过在集成前,我们需要部署一个Docker版本的HiAuth。Docker版的本地安装部署,依赖`PostgreSQL16+`、`Redis`,如果需要运行"
  },
  {
    "path": "docs/zh/guide/frontend.md",
    "chars": 6,
    "preview": "编辑中..."
  },
  {
    "path": "docs/zh/guide/hiauth-client.md",
    "chars": 6,
    "preview": "编辑中..."
  },
  {
    "path": "docs/zh/guide/issue.md",
    "chars": 7,
    "preview": "编辑中...\n"
  },
  {
    "path": "docs/zh/guide/k8s.md",
    "chars": 6,
    "preview": "编辑中..."
  },
  {
    "path": "docs/zh/guide/quick-start.md",
    "chars": 350,
    "preview": "# 快速体验 {#quikc-start}\n\n## 管理后台 {#admin}\n\n在 [Admin端](http://auth.hiauth.cn/admin) 上体验。\n- 系统管理员账号:admin\\123456,可以看到所有的配置。通"
  },
  {
    "path": "docs/zh/guide/saas.md",
    "chars": 5743,
    "preview": "# SaaS版 {#saas}\n\nSaaS版的集成,需要用户在HiAuth上开通账号、添加应,并进行相关的设置后,使用你获取的 `client-id` 和 `client-secret` 进行集成。这里为了快速验证,我们使用系统中提供的de"
  },
  {
    "path": "docs/zh/guide/sourcecode.md",
    "chars": 2417,
    "preview": "# 源码版 {#sourcecode}\n源码版的集成过程和Docker版类似,只不过将Docker版本的HiAuth改为源码编译启动。\n\n## 环境要求 {#env-demand}\n- Git\n- JDK 17+\n- Maven 3.8+\n"
  },
  {
    "path": "docs/zh/guide/test.md",
    "chars": 6,
    "preview": "编辑中..."
  },
  {
    "path": "docs/zh/guide/what-is-hiauth.md",
    "chars": 1631,
    "preview": "# HiAuth是什么? {#what-is-hiauth}\n\nHiAuth是一个基于OAuth2.0协议的认证授权系统,通过集成HiAuth系统可以快速的开启应用的认证和授权功能。HiAuth支持SaaS模式、Docker私有化部署模式、"
  },
  {
    "path": "docs/zh/index.md",
    "chars": 804,
    "preview": "---\nlayout: home\n\ntitle: HiAuth\ntitleTemplate: 基于OAuth2.0协议的认证授权服务\n\nhero:\n  name: HiAuth\n  text: 基于OAuth2.0协议的认证授权服务\n  t"
  },
  {
    "path": "example/demo/pom.xml",
    "chars": 1603,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://mave"
  },
  {
    "path": "example/demo/src/main/java/cn/hiauth/demo/DemoApplication.java",
    "chars": 315,
    "preview": "package cn.hiauth.demo;\n\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.boot.autoconfigur"
  },
  {
    "path": "example/demo/src/main/java/cn/hiauth/demo/IndexController.java",
    "chars": 1899,
    "preview": "package cn.hiauth.demo;\n\nimport org.springframework.beans.factory.annotation.Value;\nimport org.springframework.http.Http"
  },
  {
    "path": "example/demo/src/main/resources/application.yml",
    "chars": 1190,
    "preview": "server.port: 9000\n\nlogging.level:\n  root: DEBUG\n\nspring.security.oauth2.client:\n  provider:\n    #认证服务器信息\n    hiauth-serv"
  },
  {
    "path": "example/hiauth-client/pom.xml",
    "chars": 3705,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xmlns=\"ht"
  },
  {
    "path": "example/hiauth-client/src/main/java/cn/hiauth/hiauthclient/HiauthClientStarter.java",
    "chars": 470,
    "preview": "package cn.hiauth.hiauthclient;\n\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.boot.auto"
  },
  {
    "path": "example/hiauth-client/src/main/java/cn/hiauth/hiauthclient/config/WebMvcConfig.java",
    "chars": 767,
    "preview": "package cn.hiauth.hiauthclient.config;\n\nimport org.springframework.context.annotation.Configuration;\nimport org.springfr"
  },
  {
    "path": "example/hiauth-client/src/main/java/cn/hiauth/hiauthclient/controller/ApiController.java",
    "chars": 789,
    "preview": "package cn.hiauth.hiauthclient.controller;\n\nimport cn.hiauth.client.Authentication;\nimport cn.hiauth.client.SessionConte"
  },
  {
    "path": "example/hiauth-client/src/main/java/cn/hiauth/hiauthclient/controller/IndexController.java",
    "chars": 1790,
    "preview": "package cn.hiauth.hiauthclient.controller;\n\nimport cn.hiauth.client.Authentication;\nimport cn.hiauth.client.Constant;\nim"
  },
  {
    "path": "example/hiauth-client/src/main/resources/application.yml",
    "chars": 1539,
    "preview": "server.port: 9000\n\nlogging.level:\n  root: INFO\n  cn.hiauth: DEBUG\n\nspring.security.oauth2.client:\n  provider:\n    #认证服务器"
  },
  {
    "path": "example/hiauth-client/src/main/resources/logback.xml",
    "chars": 2120,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<configuration debug=\"false\">\n\n    <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5"
  },
  {
    "path": "example/hiauth-client/src/main/resources/static/css/index.css",
    "chars": 1411,
    "preview": "/* Space out content a bit */\nbody {\n  padding-top: 20px;\n  padding-bottom: 20px;\n}\n\n/* Everything but the jumbotron get"
  },
  {
    "path": "example/hiauth-client/src/main/resources/templates/demo.html",
    "chars": 2906,
    "preview": "<!DOCTYPE html>\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:th=\"https://www.thymeleaf.org\" xmlns:sec=\"https://www.t"
  },
  {
    "path": "example/hiauth-client/src/main/resources/templates/index.html",
    "chars": 2143,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\" xmlns:th=\"http://www.thymeleaf.org\">\n<head>\n    <title>HiMall</title>\n    <meta charset="
  },
  {
    "path": "example/hiauth-client/src/main/resources/templates/profile.html",
    "chars": 3736,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\" xmlns:th=\"http://www.thymeleaf.org\">\n<head>\n    <title>HiMall</title>\n    <meta charset="
  },
  {
    "path": "example/hiauth-client-exp/pom.xml",
    "chars": 2459,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://mave"
  },
  {
    "path": "example/hiauth-client-exp/src/main/java/cn/hiauth/client/ClientStarter.java",
    "chars": 313,
    "preview": "package cn.hiauth.client;\n\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.boot.autoconfig"
  },
  {
    "path": "example/hiauth-client-exp/src/main/java/cn/hiauth/client/config/BeanConfig.java",
    "chars": 140,
    "preview": "package cn.hiauth.client.config;\n\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration\npublic cl"
  },
  {
    "path": "example/hiauth-client-exp/src/main/java/cn/hiauth/client/config/SecurityConfig.java",
    "chars": 253,
    "preview": "package cn.hiauth.client.config;\n\nimport org.springframework.context.annotation.Configuration;\nimport org.springframewor"
  },
  {
    "path": "example/hiauth-client-exp/src/main/java/cn/hiauth/client/config/WebMvcConfig.java",
    "chars": 896,
    "preview": "package cn.hiauth.client.config;\n\nimport org.springframework.beans.factory.annotation.Value;\nimport org.springframework."
  },
  {
    "path": "example/hiauth-client-exp/src/main/java/cn/hiauth/client/controller/ClientController.java",
    "chars": 136,
    "preview": "package cn.hiauth.client.controller;\n\nimport org.springframework.stereotype.Controller;\n\n@Controller\npublic class Client"
  },
  {
    "path": "example/hiauth-client-exp/src/main/resources/application.yml",
    "chars": 827,
    "preview": "server.port: 9000\n\nspring.security.oauth2.client:\n  provider:\n    hiauth-code:\n      issuer-uri: http://localhost:8080\n "
  },
  {
    "path": "example/hiauth-client-exp/src/main/resources/logback.xml",
    "chars": 2190,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<configuration debug=\"false\">\n\n    <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5"
  },
  {
    "path": "example/hiauth-client-exp/src/main/resources/templates/index.html",
    "chars": 274,
    "preview": "<!DOCTYPE html>\n<html xmlns:th=\"http://www.thymeleaf.org\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>OAuth2 Client De"
  },
  {
    "path": "example/hiauth-server-exp/pom.xml",
    "chars": 4670,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://mave"
  },
  {
    "path": "example/hiauth-server-exp/src/main/java/cn/hiauth/server/ServerStarter.java",
    "chars": 493,
    "preview": "package cn.hiauth.server;\n\nimport cn.webestar.scms.commons.Constant;\nimport org.springframework.boot.SpringApplication;\n"
  },
  {
    "path": "example/hiauth-server-exp/src/main/java/cn/hiauth/server/config/AuthServerConfig.java",
    "chars": 4962,
    "preview": "package cn.hiauth.server.config;\n\nimport cn.hiauth.server.federation.FederatedIdentityIdTokenCustomizer;\nimport cn.hiaut"
  },
  {
    "path": "example/hiauth-server-exp/src/main/java/cn/hiauth/server/config/BeanConfig.java",
    "chars": 181,
    "preview": "package cn.hiauth.server.config;\n\nimport lombok.extern.slf4j.Slf4j;\nimport org.springframework.context.annotation.Config"
  },
  {
    "path": "example/hiauth-server-exp/src/main/java/cn/hiauth/server/config/SecurityConfig.java",
    "chars": 2601,
    "preview": "package cn.hiauth.server.config;\n\nimport cn.hiauth.server.federation.FederatedIdentityAuthenticationSuccessHandler;\nimpo"
  },
  {
    "path": "example/hiauth-server-exp/src/main/java/cn/hiauth/server/config/WebMvcConfig.java",
    "chars": 896,
    "preview": "package cn.hiauth.server.config;\n\nimport org.springframework.beans.factory.annotation.Value;\nimport org.springframework."
  },
  {
    "path": "example/hiauth-server-exp/src/main/java/cn/hiauth/server/controller/IndexController.java",
    "chars": 135,
    "preview": "package cn.hiauth.server.controller;\n\nimport org.springframework.stereotype.Controller;\n\n@Controller\npublic class IndexC"
  },
  {
    "path": "example/hiauth-server-exp/src/main/java/cn/hiauth/server/controller/LoginController.java",
    "chars": 176,
    "preview": "package cn.hiauth.server.controller;\n\nimport lombok.extern.slf4j.Slf4j;\nimport org.springframework.stereotype.Controller"
  },
  {
    "path": "example/hiauth-server-exp/src/main/java/cn/hiauth/server/federation/FederatedIdentityAuthenticationSuccessHandler.java",
    "chars": 2850,
    "preview": "/*\n * Copyright 2020-2025 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lic"
  },
  {
    "path": "example/hiauth-server-exp/src/main/java/cn/hiauth/server/federation/FederatedIdentityIdTokenCustomizer.java",
    "chars": 3429,
    "preview": "/*\n * Copyright 2020-2025 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lic"
  },
  {
    "path": "example/hiauth-server-exp/src/main/java/cn/hiauth/server/mapper/SimpleJdbcRegisteredClientRepository.java",
    "chars": 1930,
    "preview": "package cn.hiauth.server.mapper;\n\nimport org.springframework.jdbc.core.JdbcOperations;\nimport org.springframework.jdbc.c"
  },
  {
    "path": "example/hiauth-server-exp/src/main/java/cn/hiauth/server/utils/jose/Jwks.java",
    "chars": 2375,
    "preview": "/*\n * Copyright 2020-2023 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lic"
  },
  {
    "path": "example/hiauth-server-exp/src/main/java/cn/hiauth/server/utils/jose/KeyGeneratorUtils.java",
    "chars": 3132,
    "preview": "/*\n * Copyright 2020-2023 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lic"
  },
  {
    "path": "example/hiauth-server-exp/src/main/java/cn/hiauth/server/utils/package-info.java",
    "chars": 31,
    "preview": "package cn.hiauth.server.utils;"
  },
  {
    "path": "example/hiauth-server-exp/src/main/resources/application-hiauth.yml",
    "chars": 753,
    "preview": "server.port: 8080\n\nlogging.level:\n  root: INFO\n  cn.hiauth: DEBUG\n  com.alibaba.nacos: INFO\n  org.springframework.data.r"
  },
  {
    "path": "example/hiauth-server-exp/src/main/resources/application-redis.yml",
    "chars": 203,
    "preview": "# 单节点写法\nspring.data.redis:\n  host: ${redis.host}\n  port: ${redis.port}\n  database: ${redis.database}\n  username: ${redis"
  },
  {
    "path": "example/hiauth-server-exp/src/main/resources/application.yml",
    "chars": 598,
    "preview": "app.version: '@project.version@'\napp.build.timestamp: '@app.build.timestamp@'\nspring.application.name: hiauth-server\n\n# "
  },
  {
    "path": "example/hiauth-server-exp/src/main/resources/logback.xml",
    "chars": 2127,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<configuration debug=\"false\">\n\n    <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5"
  },
  {
    "path": "example/hiauth-server-exp/src/main/resources/templates/index.html",
    "chars": 160,
    "preview": "<!doctype html>\n<html lang=\"en\" xmlns:th=\"http://www.thymeleaf.org\">\n<head>\n</head>\n<body>\nindex\n<a class=\"dropdown-item"
  },
  {
    "path": "example/himall/pom.xml",
    "chars": 3300,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xmlns=\"ht"
  },
  {
    "path": "example/himall/src/main/java/cn/hiauth/himall/HiMallStarter.java",
    "chars": 313,
    "preview": "package cn.hiauth.himall;\n\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.boot.autoconfig"
  },
  {
    "path": "example/himall/src/main/java/cn/hiauth/himall/config/SecurityConfig.java",
    "chars": 1860,
    "preview": "package cn.hiauth.himall.config;\n\nimport org.springframework.boot.web.client.RestTemplateBuilder;\nimport org.springframe"
  },
  {
    "path": "example/himall/src/main/java/cn/hiauth/himall/config/WebMvcConfig.java",
    "chars": 761,
    "preview": "package cn.hiauth.himall.config;\n\nimport org.springframework.context.annotation.Configuration;\nimport org.springframewor"
  },
  {
    "path": "example/himall/src/main/java/cn/hiauth/himall/controller/AuthController.java",
    "chars": 858,
    "preview": "package cn.hiauth.himall.controller;\n\nimport jakarta.servlet.http.HttpServletRequest;\nimport org.springframework.securit"
  },
  {
    "path": "example/himall/src/main/java/cn/hiauth/himall/controller/IndexController.java",
    "chars": 3212,
    "preview": "package cn.hiauth.himall.controller;\n\nimport jakarta.servlet.http.Cookie;\nimport jakarta.servlet.http.HttpServletRequest"
  },
  {
    "path": "example/himall/src/main/resources/application.yml",
    "chars": 1255,
    "preview": "server.port: 9000\n\nlogging.level:\n  root: DEBUG\n  cn.hiauth: DEBUG\n\nspring.security.oauth2.client:\n  provider:\n    #认证服务"
  },
  {
    "path": "example/himall/src/main/resources/logback.xml",
    "chars": 2113,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<configuration debug=\"false\">\n\n    <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5"
  },
  {
    "path": "example/himall/src/main/resources/static/css/index.css",
    "chars": 1411,
    "preview": "/* Space out content a bit */\nbody {\n  padding-top: 20px;\n  padding-bottom: 20px;\n}\n\n/* Everything but the jumbotron get"
  },
  {
    "path": "example/himall/src/main/resources/templates/demo.html",
    "chars": 2906,
    "preview": "<!DOCTYPE html>\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:th=\"https://www.thymeleaf.org\" xmlns:sec=\"https://www.t"
  },
  {
    "path": "example/himall/src/main/resources/templates/index.html",
    "chars": 2157,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\" xmlns:th=\"http://www.thymeleaf.org\">\n<head>\n    <title>HiMall</title>\n    <meta charset="
  },
  {
    "path": "example/himall/src/main/resources/templates/profile.html",
    "chars": 3749,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\" xmlns:th=\"http://www.thymeleaf.org\">\n<head>\n    <title>HiMall</title>\n    <meta charset="
  },
  {
    "path": "example/resource/pom.xml",
    "chars": 1952,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://mave"
  },
  {
    "path": "example/resource/src/main/java/cn/hiauth/resource/ResourceStarter.java",
    "chars": 319,
    "preview": "package cn.hiauth.resource;\n\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.boot.autoconf"
  },
  {
    "path": "example/resource/src/main/java/cn/hiauth/resource/config/ResourceServerConfig.java",
    "chars": 1476,
    "preview": "package cn.hiauth.resource.config;\n\nimport cn.hiauth.resource.config.auth.SimpleAccessDeniedHandler;\nimport cn.hiauth.re"
  },
  {
    "path": "example/resource/src/main/java/cn/hiauth/resource/config/auth/SimpleAccessDeniedHandler.java",
    "chars": 1057,
    "preview": "package cn.hiauth.resource.config.auth;\n\nimport cn.hiauth.resource.utils.ResponseTools;\nimport cn.webestar.scms.commons."
  },
  {
    "path": "example/resource/src/main/java/cn/hiauth/resource/config/auth/SimpleAuthenticationEntryPoint.java",
    "chars": 1836,
    "preview": "package cn.hiauth.resource.config.auth;\n\nimport cn.hiauth.resource.utils.ResponseTools;\nimport cn.webestar.scms.commons."
  },
  {
    "path": "example/resource/src/main/java/cn/hiauth/resource/controller/IndexController.java",
    "chars": 292,
    "preview": "package cn.hiauth.resource.controller;\n\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springfram"
  },
  {
    "path": "example/resource/src/main/java/cn/hiauth/resource/controller/ProfileController.java",
    "chars": 564,
    "preview": "package cn.hiauth.resource.controller;\n\nimport cn.webestar.scms.commons.R;\nimport org.springframework.security.access.pr"
  },
  {
    "path": "example/resource/src/main/java/cn/hiauth/resource/controller/UnpapiController.java",
    "chars": 690,
    "preview": "package cn.hiauth.resource.controller;\n\nimport cn.webestar.scms.commons.R;\nimport org.springframework.web.bind.annotatio"
  },
  {
    "path": "example/resource/src/main/java/cn/hiauth/resource/controller/UserController.java",
    "chars": 552,
    "preview": "package cn.hiauth.resource.controller;\n\nimport cn.webestar.scms.commons.R;\nimport org.springframework.security.access.pr"
  },
  {
    "path": "example/resource/src/main/java/cn/hiauth/resource/utils/ResponseTools.java",
    "chars": 1123,
    "preview": "package cn.hiauth.resource.utils;\n\nimport cn.webestar.scms.commons.R;\nimport com.fasterxml.jackson.annotation.JsonInclud"
  },
  {
    "path": "example/resource/src/main/resources/application.yml",
    "chars": 311,
    "preview": "server.port: 9002\n\nlogging.level:\n  root: DEBUG\n\nspring.jackson:\n  default-property-inclusion: NON_NULL\n  serialization:"
  },
  {
    "path": "example/resource/src/main/resources/logback.xml",
    "chars": 2115,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<configuration debug=\"false\">\n\n    <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5"
  },
  {
    "path": "example/spring-cloud/README.md",
    "chars": 78,
    "preview": "- 访问:http://auth.hiauth.cn,如果是登录状态,先退出登录\n- 然后访问:http://127.0.0.1:9000/ordersvc"
  },
  {
    "path": "example/spring-cloud/gateway/pom.xml",
    "chars": 3370,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://mave"
  },
  {
    "path": "example/spring-cloud/gateway/src/main/java/cn/hiauth/gateway/ApiController.java",
    "chars": 606,
    "preview": "package cn.hiauth.gateway;\n\nimport org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;\n"
  },
  {
    "path": "example/spring-cloud/gateway/src/main/java/cn/hiauth/gateway/GatewayStarter.java",
    "chars": 316,
    "preview": "package cn.hiauth.gateway;\n\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.boot.autoconfi"
  },
  {
    "path": "example/spring-cloud/gateway/src/main/java/cn/hiauth/gateway/IndexController.java",
    "chars": 364,
    "preview": "package cn.hiauth.gateway;\n\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bi"
  },
  {
    "path": "example/spring-cloud/gateway/src/main/java/cn/hiauth/gateway/SecurityConfig.java",
    "chars": 2641,
    "preview": "package cn.hiauth.gateway;\n\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annot"
  },
  {
    "path": "example/spring-cloud/gateway/src/main/resources/application.yml",
    "chars": 1538,
    "preview": "server.port: 9000\nspring.application.name: gateway\nlogging.level.root: INFO\n\n# Nacos注册中心配置\nspring.cloud.nacos.discovery."
  },
  {
    "path": "example/spring-cloud/gateway/src/main/resources/logback.xml",
    "chars": 2114,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<configuration debug=\"false\">\n\n    <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5"
  },
  {
    "path": "example/spring-cloud/ordersvc/pom.xml",
    "chars": 2548,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://mave"
  },
  {
    "path": "example/spring-cloud/ordersvc/src/main/java/cn/hiauth/gateway/IndexController.java",
    "chars": 407,
    "preview": "package cn.hiauth.gateway;\n\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bi"
  },
  {
    "path": "example/spring-cloud/ordersvc/src/main/java/cn/hiauth/gateway/OrderStarter.java",
    "chars": 408,
    "preview": "package cn.hiauth.gateway;\n\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.boot.autoconfi"
  },
  {
    "path": "example/spring-cloud/ordersvc/src/main/resources/application.yml",
    "chars": 152,
    "preview": "server.port: 9001\nspring.application.name: ordersvc\nlogging.level.root: INFO\n\n# Nacos注册中心配置\nspring.cloud.nacos.discovery"
  },
  {
    "path": "example/spring-cloud/ordersvc/src/main/resources/logback.xml",
    "chars": 2115,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<configuration debug=\"false\">\n\n    <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5"
  },
  {
    "path": "example/spring-cloud/pom.xml",
    "chars": 556,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xmlns=\"ht"
  },
  {
    "path": "example/spring-cloud-with-hiauth-client/README.md",
    "chars": 218,
    "preview": "- 清空登录状态:访问 http://auth.hiauth.cn,如果是登录状态,先退出登录;\n- 登录授权:访问 http://127.0.0.1:9000/unpapi/himall/oauth2/login\n- 访问接口:登录成功后"
  },
  {
    "path": "example/spring-cloud-with-hiauth-client/gateway1/pom.xml",
    "chars": 3988,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://mave"
  },
  {
    "path": "example/spring-cloud-with-hiauth-client/gateway1/src/main/java/cn/hiauth/gateway/ApiController.java",
    "chars": 738,
    "preview": "package cn.hiauth.gateway;\n\nimport cn.hiauth.client.Authentication;\nimport cn.hiauth.client.SessionContextHolder;\nimport"
  },
  {
    "path": "example/spring-cloud-with-hiauth-client/gateway1/src/main/java/cn/hiauth/gateway/GatewayStarter.java",
    "chars": 491,
    "preview": "package cn.hiauth.gateway;\n\nimport cn.hiauth.client.Constant;\nimport org.springframework.boot.SpringApplication;\nimport "
  },
  {
    "path": "example/spring-cloud-with-hiauth-client/gateway1/src/main/java/cn/hiauth/gateway/IndexController.java",
    "chars": 364,
    "preview": "package cn.hiauth.gateway;\n\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bi"
  },
  {
    "path": "example/spring-cloud-with-hiauth-client/gateway1/src/main/resources/application.yml",
    "chars": 1151,
    "preview": "server.port: 9000\nspring.application.name: gateway\nlogging.level.root: INFO\n\n# 网关启动方式\nspring.main.web-application-type: "
  },
  {
    "path": "example/spring-cloud-with-hiauth-client/gateway1/src/main/resources/logback.xml",
    "chars": 2114,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<configuration debug=\"false\">\n\n    <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5"
  },
  {
    "path": "example/spring-cloud-with-hiauth-client/ordersvc1/pom.xml",
    "chars": 2749,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://mave"
  },
  {
    "path": "example/spring-cloud-with-hiauth-client/ordersvc1/src/main/java/cn/hiauth/gateway/IndexController.java",
    "chars": 591,
    "preview": "package cn.hiauth.gateway;\n\nimport cn.hiauth.client.Authentication;\nimport cn.hiauth.client.SessionContextHolder;\nimport"
  },
  {
    "path": "example/spring-cloud-with-hiauth-client/ordersvc1/src/main/java/cn/hiauth/gateway/OrderStarter.java",
    "chars": 583,
    "preview": "package cn.hiauth.gateway;\n\nimport cn.hiauth.client.Constant;\nimport org.springframework.boot.SpringApplication;\nimport "
  },
  {
    "path": "example/spring-cloud-with-hiauth-client/ordersvc1/src/main/resources/application.yml",
    "chars": 389,
    "preview": "server.port: 9001\nspring.application.name: ordersvc\nlogging.level.root: INFO\n\n# Nacos注册中心配置\nspring.cloud.nacos.discovery"
  },
  {
    "path": "example/spring-cloud-with-hiauth-client/ordersvc1/src/main/resources/logback.xml",
    "chars": 2115,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<configuration debug=\"false\">\n\n    <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5"
  },
  {
    "path": "example/spring-cloud-with-hiauth-client/pom.xml",
    "chars": 577,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xmlns=\"ht"
  },
  {
    "path": "example/wechat-login/pom.xml",
    "chars": 3062,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xmlns=\"ht"
  },
  {
    "path": "example/wechat-login/src/main/java/cn/hiauth/wechatlogin/WechatLoginStarter.java",
    "chars": 328,
    "preview": "package cn.hiauth.wechatlogin;\n\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.boot.autoc"
  },
  {
    "path": "example/wechat-login/src/main/java/cn/hiauth/wechatlogin/config/SecurityConfig.java",
    "chars": 5652,
    "preview": "package cn.hiauth.wechatlogin.config;\n\nimport cn.hiauth.wechatlogin.config.web.security.phone.SmsCodeAuthenticationFilte"
  },
  {
    "path": "example/wechat-login/src/main/java/cn/hiauth/wechatlogin/config/WebMvcConfig.java",
    "chars": 766,
    "preview": "package cn.hiauth.wechatlogin.config;\n\nimport org.springframework.context.annotation.Configuration;\nimport org.springfra"
  },
  {
    "path": "example/wechat-login/src/main/java/cn/hiauth/wechatlogin/config/web/auth/package-info.java",
    "chars": 46,
    "preview": "package cn.hiauth.wechatlogin.config.web.auth;"
  },
  {
    "path": "example/wechat-login/src/main/java/cn/hiauth/wechatlogin/config/web/security/phone/SmsCodeAuthenticationFilter.java",
    "chars": 1522,
    "preview": "package cn.hiauth.wechatlogin.config.web.security.phone;\n\nimport jakarta.servlet.http.HttpServletRequest;\nimport jakarta"
  },
  {
    "path": "example/wechat-login/src/main/java/cn/hiauth/wechatlogin/config/web/security/phone/SmsCodeAuthenticationProvider.java",
    "chars": 1775,
    "preview": "package cn.hiauth.wechatlogin.config.web.security.phone;\n\nimport cn.hiauth.wechatlogin.service.CustomUserDetailsService;"
  },
  {
    "path": "example/wechat-login/src/main/java/cn/hiauth/wechatlogin/config/web/security/phone/SmsCodeAuthenticationToken.java",
    "chars": 992,
    "preview": "package cn.hiauth.wechatlogin.config.web.security.phone;\n\nimport org.springframework.security.authentication.AbstractAut"
  },
  {
    "path": "example/wechat-login/src/main/java/cn/hiauth/wechatlogin/config/web/security/wechat/QrCodeAuthenticationFilter.java",
    "chars": 1046,
    "preview": "package cn.hiauth.wechatlogin.config.web.security.wechat;\n\nimport jakarta.servlet.http.HttpServletRequest;\nimport jakart"
  },
  {
    "path": "example/wechat-login/src/main/java/cn/hiauth/wechatlogin/config/web/security/wechat/QrCodeAuthenticationProvider.java",
    "chars": 1698,
    "preview": "package cn.hiauth.wechatlogin.config.web.security.wechat;\n\nimport cn.hiauth.wechatlogin.service.CustomUserDetailsService"
  },
  {
    "path": "example/wechat-login/src/main/java/cn/hiauth/wechatlogin/config/web/security/wechat/QrCodeAuthenticationToken.java",
    "chars": 973,
    "preview": "package cn.hiauth.wechatlogin.config.web.security.wechat;\n\nimport org.springframework.security.authentication.AbstractAu"
  },
  {
    "path": "example/wechat-login/src/main/java/cn/hiauth/wechatlogin/controller/AuthController.java",
    "chars": 156,
    "preview": "package cn.hiauth.wechatlogin.controller;\n\nimport org.springframework.web.bind.annotation.RestController;\n\n@RestControll"
  },
  {
    "path": "example/wechat-login/src/main/java/cn/hiauth/wechatlogin/controller/IndexController.java",
    "chars": 1047,
    "preview": "package cn.hiauth.wechatlogin.controller;\n\nimport jakarta.servlet.http.HttpServletRequest;\nimport jakarta.servlet.http.H"
  },
  {
    "path": "example/wechat-login/src/main/java/cn/hiauth/wechatlogin/entity/CustomUserDetails.java",
    "chars": 1352,
    "preview": "package cn.hiauth.wechatlogin.entity;\n\nimport org.springframework.security.core.GrantedAuthority;\nimport org.springframe"
  },
  {
    "path": "example/wechat-login/src/main/java/cn/hiauth/wechatlogin/service/CustomUserDetailsService.java",
    "chars": 2135,
    "preview": "package cn.hiauth.wechatlogin.service;\n\nimport cn.hiauth.wechatlogin.entity.CustomUserDetails;\nimport org.springframewor"
  },
  {
    "path": "example/wechat-login/src/main/resources/application.yml",
    "chars": 66,
    "preview": "server.port: 9000\n\nlogging.level:\n  root: INFO\n  cn.hiauth: DEBUG\n"
  },
  {
    "path": "example/wechat-login/src/main/resources/logback.xml",
    "chars": 2113,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<configuration debug=\"false\">\n\n    <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5"
  },
  {
    "path": "example/wechat-login/src/main/resources/templates/home.html",
    "chars": 373,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\" xmlns:th=\"http://www.thymeleaf.org\">\n<head>\n    <title>HiMall</title>\n    <meta charset="
  },
  {
    "path": "example/wechat-login/src/main/resources/templates/index.html",
    "chars": 590,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\" xmlns:th=\"http://www.thymeleaf.org\">\n<head>\n    <title>HiMall</title>\n    <meta charset="
  },
  {
    "path": "example/wechat-login/src/main/resources/templates/login.html",
    "chars": 1882,
    "preview": "<!DOCTYPE html>\n<html xmlns:th=\"http://www.thymeleaf.org\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Custom Login Pag"
  },
  {
    "path": "hiauth-client-starter/hiauth-client-commons/pom.xml",
    "chars": 5609,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xmlns=\"ht"
  },
  {
    "path": "hiauth-client-starter/hiauth-client-commons/src/main/java/cn/hiauth/client/Authentication.java",
    "chars": 462,
    "preview": "package cn.hiauth.client;\n\nimport lombok.Data;\n\nimport java.util.List;\nimport java.util.Map;\n\n@Data\npublic class Authent"
  },
  {
    "path": "hiauth-client-starter/hiauth-client-commons/src/main/java/cn/hiauth/client/Client.java",
    "chars": 459,
    "preview": "package cn.hiauth.client;\n\nimport lombok.Data;\n\n@Data\npublic class Client {\n\n    private String clientId;\n    private St"
  },
  {
    "path": "hiauth-client-starter/hiauth-client-commons/src/main/java/cn/hiauth/client/Constant.java",
    "chars": 955,
    "preview": "package cn.hiauth.client;\n\npublic class Constant {\n\n    public final static String RESULT_JSON = \"{ \\\"code\\\": %d, \\\"mess"
  },
  {
    "path": "hiauth-client-starter/hiauth-client-commons/src/main/java/cn/hiauth/client/HiAuthToken.java",
    "chars": 243,
    "preview": "package cn.hiauth.client;\n\nimport lombok.Data;\n\nimport java.time.LocalDateTime;\n\n@Data\npublic class HiAuthToken {\n\n    p"
  },
  {
    "path": "hiauth-client-starter/hiauth-client-commons/src/main/java/cn/hiauth/client/JwtUtils.java",
    "chars": 1262,
    "preview": "package cn.hiauth.client;\n\nimport cn.hutool.jwt.JWT;\nimport cn.hutool.jwt.JWTPayload;\nimport cn.hutool.jwt.JWTUtil;\n\nimp"
  },
  {
    "path": "hiauth-client-starter/hiauth-client-commons/src/main/java/cn/hiauth/client/SecurityCorp.java",
    "chars": 235,
    "preview": "package cn.hiauth.client;\n\nimport lombok.Data;\n\n@Data\npublic class SecurityCorp {\n\n    private Long id;\n    private Stri"
  },
  {
    "path": "hiauth-client-starter/hiauth-client-commons/src/main/java/cn/hiauth/client/SecurityService.java",
    "chars": 332,
    "preview": "package cn.hiauth.client;\n\nimport java.util.List;\n\n/**\n * @author zgs\n */\npublic interface SecurityService {\n\n    Securi"
  },
  {
    "path": "hiauth-client-starter/hiauth-client-commons/src/main/java/cn/hiauth/client/SecurityUser.java",
    "chars": 85,
    "preview": "package cn.hiauth.client;\n\nimport lombok.Data;\n\n@Data\npublic class SecurityUser {\n\n}\n"
  },
  {
    "path": "hiauth-client-starter/hiauth-client-commons/src/main/java/cn/hiauth/client/SessionContext.java",
    "chars": 775,
    "preview": "package cn.hiauth.client;\n\nimport lombok.Data;\n\nimport java.io.Serializable;\nimport java.time.LocalDateTime;\nimport java"
  },
  {
    "path": "hiauth-client-starter/hiauth-client-commons/src/main/java/cn/hiauth/client/SessionContextHolder.java",
    "chars": 3792,
    "preview": "package cn.hiauth.client;\n\nimport cn.hutool.json.JSONUtil;\nimport org.springframework.data.redis.core.RedisTemplate;\n\nim"
  },
  {
    "path": "hiauth-client-starter/hiauth-client-commons/src/main/java/cn/hiauth/client/TokenVo.java",
    "chars": 1093,
    "preview": "package cn.hiauth.client;\n\npublic class TokenVo {\n\n    private String accessToken;\n    private Integer expireIn;\n    pri"
  },
  {
    "path": "hiauth-client-starter/hiauth-client-commons/src/main/java/cn/hiauth/client/UserinfoVo.java",
    "chars": 1145,
    "preview": "package cn.hiauth.client;\n\nimport lombok.Data;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n@Data\npublic class U"
  },
  {
    "path": "hiauth-client-starter/hiauth-client-resource-spring-boot-starter/pom.xml",
    "chars": 6470,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xmlns=\"ht"
  },
  {
    "path": "hiauth-client-starter/hiauth-client-resource-spring-boot-starter/src/main/java/cn/hiauth/client/resource/HiAuthClientResourceAutoConfig.java",
    "chars": 380,
    "preview": "package cn.hiauth.client.resource;\n\nimport lombok.extern.slf4j.Slf4j;\nimport org.springframework.boot.context.properties"
  },
  {
    "path": "hiauth-client-starter/hiauth-client-resource-spring-boot-starter/src/main/java/cn/hiauth/client/resource/HiAuthClientResourceProperties.java",
    "chars": 293,
    "preview": "package cn.hiauth.client.resource;\n\nimport lombok.Data;\nimport org.springframework.boot.context.properties.Configuration"
  },
  {
    "path": "hiauth-client-starter/hiauth-client-resource-spring-boot-starter/src/main/resources/META-INF/spring-configuration-metadata.json",
    "chars": 122,
    "preview": "{\n  \"properties\": {\n    \"hiauth.client.resource.url\": {\n      \"description\": \"授权服务端地址\",\n      \"type\": \"string\"\n    }\n  }"
  },
  {
    "path": "hiauth-client-starter/hiauth-client-resource-spring-boot-starter/src/main/resources/META-INF/spring.factories",
    "chars": 119,
    "preview": "org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.hiauth.client.resource.HiAuthClientResourceAutoConfig"
  },
  {
    "path": "hiauth-client-starter/hiauth-client-session-spring-boot-starter/pom.xml",
    "chars": 6467,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xmlns=\"ht"
  },
  {
    "path": "hiauth-client-starter/hiauth-client-session-spring-boot-starter/src/main/java/cn/hiauth/client/session/AuthFilter.java",
    "chars": 5195,
    "preview": "package cn.hiauth.client.session;\n\nimport cn.hiauth.client.Constant;\nimport cn.hiauth.client.JwtUtils;\nimport cn.hiauth."
  },
  {
    "path": "hiauth-client-starter/hiauth-client-session-spring-boot-starter/src/main/java/cn/hiauth/client/session/HiAuthClientSessionAutoConfig.java",
    "chars": 1540,
    "preview": "package cn.hiauth.client.session;\n\nimport lombok.extern.slf4j.Slf4j;\nimport org.springframework.beans.factory.annotation"
  },
  {
    "path": "hiauth-client-starter/hiauth-client-session-spring-boot-starter/src/main/java/cn/hiauth/client/session/HiAuthClientSessionCacheConfig.java",
    "chars": 2436,
    "preview": "package cn.hiauth.client.session;\n\nimport com.fasterxml.jackson.annotation.JsonAutoDetect;\nimport com.fasterxml.jackson."
  },
  {
    "path": "hiauth-client-starter/hiauth-client-session-spring-boot-starter/src/main/java/cn/hiauth/client/session/HiAuthClientSessionController.java",
    "chars": 1230,
    "preview": "package cn.hiauth.client.session;\n\nimport cn.hiauth.client.*;\nimport cn.webestar.scms.commons.R;\nimport lombok.extern.sl"
  },
  {
    "path": "hiauth-client-starter/hiauth-client-session-spring-boot-starter/src/main/java/cn/hiauth/client/session/HiAuthClientSessionProperties.java",
    "chars": 579,
    "preview": "package cn.hiauth.client.session;\n\nimport lombok.Data;\nimport org.springframework.boot.context.properties.ConfigurationP"
  },
  {
    "path": "hiauth-client-starter/hiauth-client-session-spring-boot-starter/src/main/java/cn/hiauth/client/session/HiAuthClientSessionRunner.java",
    "chars": 710,
    "preview": "package cn.hiauth.client.session;\n\nimport cn.hiauth.client.SessionContextHolder;\nimport lombok.extern.slf4j.Slf4j;\nimpor"
  },
  {
    "path": "hiauth-client-starter/hiauth-client-session-spring-boot-starter/src/main/resources/META-INF/spring-configuration-metadata.json",
    "chars": 477,
    "preview": "{\n  \"properties\": {\n    \"app.security.enable\": {\n      \"description\": \"开启安全拦截。默认值:false\",\n      \"type\": \"boolean\"\n    },"
  },
  {
    "path": "hiauth-client-starter/hiauth-client-session-spring-boot-starter/src/main/resources/META-INF/spring.factories",
    "chars": 117,
    "preview": "org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.hiauth.client.session.HiAuthClientSessionAutoConfig"
  },
  {
    "path": "hiauth-client-starter/hiauth-client-spring-boot-starter/docs/apisvc-oms.yml",
    "chars": 1476,
    "preview": "server.port: 9003\n\nlogging.level:\n  root: INFO\n  com.vking: DEBUG\n\napp.cache.prefix: uavs:oms\napp.security.enable: true\n"
  },
  {
    "path": "hiauth-client-starter/hiauth-client-spring-boot-starter/pom.xml",
    "chars": 6620,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xmlns=\"ht"
  },
  {
    "path": "hiauth-client-starter/hiauth-client-spring-boot-starter/src/main/java/cn/hiauth/client/AuthFilter.java",
    "chars": 6431,
    "preview": "package cn.hiauth.client;\n\nimport cn.hutool.json.JSONUtil;\nimport cn.hutool.jwt.JWT;\nimport cn.webestar.scms.commons.Ass"
  },
  {
    "path": "hiauth-client-starter/hiauth-client-spring-boot-starter/src/main/java/cn/hiauth/client/HiAuthCacheConfig.java",
    "chars": 2415,
    "preview": "package cn.hiauth.client;\n\nimport com.fasterxml.jackson.annotation.JsonAutoDetect;\nimport com.fasterxml.jackson.annotati"
  },
  {
    "path": "hiauth-client-starter/hiauth-client-spring-boot-starter/src/main/java/cn/hiauth/client/HiAuthClientAutoConfig.java",
    "chars": 1769,
    "preview": "package cn.hiauth.client;\n\nimport lombok.extern.slf4j.Slf4j;\nimport org.springframework.beans.factory.annotation.Autowir"
  },
  {
    "path": "hiauth-client-starter/hiauth-client-spring-boot-starter/src/main/java/cn/hiauth/client/HiAuthClientController.java",
    "chars": 9698,
    "preview": "package cn.hiauth.client;\n\nimport cn.hiauth.client.api.TokenVo;\nimport cn.hiauth.client.api.UserPwdUpdateDto;\nimport cn."
  },
  {
    "path": "hiauth-client-starter/hiauth-client-spring-boot-starter/src/main/java/cn/hiauth/client/HiAuthClientProperties.java",
    "chars": 948,
    "preview": "package cn.hiauth.client;\n\nimport lombok.Data;\nimport org.springframework.boot.context.properties.ConfigurationPropertie"
  },
  {
    "path": "hiauth-client-starter/hiauth-client-spring-boot-starter/src/main/java/cn/hiauth/client/HiAuthClientProviderProperties.java",
    "chars": 473,
    "preview": "package cn.hiauth.client;\n\nimport lombok.Data;\nimport org.springframework.boot.context.properties.ConfigurationPropertie"
  },
  {
    "path": "hiauth-client-starter/hiauth-client-spring-boot-starter/src/main/java/cn/hiauth/client/HiAuthClientRegistrationProperties.java",
    "chars": 618,
    "preview": "package cn.hiauth.client;\n\nimport lombok.Data;\nimport org.springframework.boot.context.properties.ConfigurationPropertie"
  },
  {
    "path": "hiauth-client-starter/hiauth-client-spring-boot-starter/src/main/java/cn/hiauth/client/HiAuthClientRunner.java",
    "chars": 649,
    "preview": "package cn.hiauth.client;\n\nimport lombok.extern.slf4j.Slf4j;\nimport org.springframework.beans.factory.annotation.Autowir"
  },
  {
    "path": "hiauth-client-starter/hiauth-client-spring-boot-starter/src/main/java/cn/hiauth/client/api/TokenVo.java",
    "chars": 1097,
    "preview": "package cn.hiauth.client.api;\n\npublic class TokenVo {\n\n    private String accessToken;\n    private Integer expireIn;\n   "
  },
  {
    "path": "hiauth-client-starter/hiauth-client-spring-boot-starter/src/main/java/cn/hiauth/client/api/UserPwdUpdateDto.java",
    "chars": 148,
    "preview": "package cn.hiauth.client.api;\n\nimport lombok.Data;\n\n@Data\npublic class UserPwdUpdateDto {\n\n    private String newPwd;\n  "
  },
  {
    "path": "hiauth-client-starter/hiauth-client-spring-boot-starter/src/main/resources/META-INF/spring-configuration-metadata.json",
    "chars": 969,
    "preview": "{\n  \"properties\": {\n    \"app.security.enable\": {\n      \"description\": \"是否启用安全拦截。默认值:false\",\n      \"type\": \"boolean\"\n    "
  },
  {
    "path": "hiauth-client-starter/hiauth-client-spring-boot-starter/src/main/resources/META-INF/spring.factories",
    "chars": 102,
    "preview": "org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.hiauth.client.HiAuthClientAutoConfig"
  },
  {
    "path": "hiauth-client-starter/hiauth-client-spring-cloud-gateway-starter/pom.xml",
    "chars": 6964,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xmlns=\"ht"
  }
]

// ... and 1840 more files (download for full content)

About this extraction

This page contains the full source code of the bestaone/HiAuth GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 2040 files (6.2 MB), approximately 1.8M tokens, and a symbol index with 2497 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!