首页 文章 精选 留言 我的

精选列表

搜索[后台会话],共10000篇文章
优秀的个人博客,低调大师

GinFast 开源后台管理框架的 Token 管理业务逻辑及源码解析

项目地址 后端项目: https://github.com/qxkjsoft/ginfast 前端项目: https://github.com/qxkjsoft/ginfast-ui 概述 本文档详细分析GinFast项目中的Token管理系统,涵盖前后端JWT令牌的生成、验证、刷新、撤销等核心业务逻辑,以及相关的源码实现。包括后端Go服务和前端Vue应用的完整Token管理流程。 系统架构 后端核心组件 TokenService - 令牌服务核心实现 JWTAuthMiddleware - JWT认证中间件 AuthController - 认证控制器 TokenHelper - 令牌工具类 前端核心组件 Http拦截器 - 自动Token管理和刷新 Auth工具类 - Token存储和格式化 用户状态管理 - Token状态维护 技术栈 后端技术 JWT (JSON Web Token) - 用于身份认证 Redis/Memory - 可配置的缓存后端,用于令牌缓存和撤销管理 Gin - Web框架 jwt-go - JWT库 前端技术 Axios - HTTP客户端 Vue 3 + TypeScript - 前端框架 js-cookie - Cookie管理 Pinia - 状态管理 核心业务逻辑 1. 令牌类型 Access Token 用途: API访问认证 过期时间: 可配置 (默认12小时/43200秒) 存储方式: 可选缓存模式 (通过配置控制) 格式: JWT 前端存储: Cookie (gin-fast-access-token) Refresh Token 用途: 刷新Access Token 过期时间: 可配置 (默认30天/2592000秒) 存储方式: 一定会缓存 (Redis或内存缓存) 格式: JWT 前端存储: Cookie (gin-fast-refresh-token) 2. 认证流程 登录流程 // 后端流程 // 1. 用户提交用户名、密码、验证码 // 2. 验证用户身份和租户权限 // 3. 生成Access Token和Refresh Token // 4. 返回令牌对给客户端 // 前端流程 // 1. 用户填写登录表单 // 2. 调用/login接口获取令牌对 // 3. 将令牌存储到Cookie // 4. 更新用户状态 令牌刷新流程 // 后端流程 // 1. 客户端提交Refresh Token // 2. 验证Refresh Token有效性 // 3. 生成新的Access Token // 4. 轮换Refresh Token(保持剩余有效期) // 5. 返回新的令牌对 // 前端流程 // 1. 检测Access Token即将过期(剩余3秒) // 2. 自动调用/refreshToken接口 // 3. 更新Cookie中的令牌信息 // 4. 重试待处理的请求 登出流程 // 后端流程 // 1. 撤销当前Access Token // 2. 撤销Refresh Token // 3. 清除相关缓存 // 前端流程 // 1. 调用登出接口 // 2. 清除Cookie中的令牌 // 3. 清除用户状态 // 4. 跳转到登录页 源码解析 1. 后端TokenService实现 核心结构体 type TokenService struct { // Ctx 上下文,用于缓存操作 Ctx context.Context // RedisHelper 缓存接口,支持Redis和内存两种实现 // 通过配置 server.cachetype 控制使用哪种缓存后端 RedisHelper app.CacheInterf // JWTSecret JWT签名密钥,用于Token的加密和解密 // 通过配置 token.jwttokensignkey 设置 JWTSecret string // TokenExpire Access Token过期时间,单位秒 // 通过配置 token.jwttokenexpire 设置,默认12小时(43200秒) TokenExpire time.Duration // RefreshExpire Refresh Token过期时间,单位秒 // 通过配置 token.jwttokenrefreshexpire 设置,默认30天(2592000秒) RefreshExpire time.Duration // CacheKeyPrefix 缓存键前缀,用于区分不同应用的缓存 // 通过配置 token.cachekeyprefix 设置,默认"gin-fast:" CacheKeyPrefix string // IsCache 是否开启Access Token缓存 // 通过配置 token.isCache 控制: // - true: 开启缓存,支持Token立即撤销,安全性更高 // - false: 关闭缓存,性能更高,但无法立即撤销Token IsCache bool } 主要方法 GenerateTokenWithCache - 生成带缓存的Access Token func (s *TokenService) GenerateTokenWithCache(user *app.ClaimsUser) (string, error) { // 1. 生成JWT令牌 tokenString, err := s.GenerateToken(user) // 2. 如果开启缓存,存储到Redis if s.IsCache { tokenInfo := &app.TokenInfo{ UserID: user.UserID, Token: tokenString, ExpiresAt: time.Now().Add(s.TokenExpire * time.Second), CreatedAt: time.Now(), } err = s.storeTokenWithCache(tokenInfo) } return tokenString, nil } ValidateTokenWithCache - 验证带缓存的Token func (s *TokenService) ValidateTokenWithCache(tokenString string) (*app.Claims, error) { // 1. 验证JWT签名 claims, err := s.ParseToken(tokenString) // 2. 检查缓存中是否存在该token(白名单模式) if s.IsCache { key := s.getTokenKeyWithCache(claims.UserID, tokenString) exists, err := s.RedisHelper.Exists(s.Ctx, key) if err != nil || exists == 0 { return nil, errors.New("token not found") } } return claims, nil } RotateRefreshToken - 轮换Refresh Token func (s *TokenService) RotateRefreshToken(oldRefreshToken string) (string, error) { // 1. 验证旧的refresh token claims, err := s.ValidateRefreshToken(oldRefreshToken) // 2. 计算剩余有效时间 remainingDuration := claims.ExpiresAt.Time.Sub(now) // 3. 撤销旧的refresh token s.RevokeRefreshToken(claims.UserID) // 4. 生成新的refresh token,使用剩余的有效时间 expirationTime := now.Add(remainingDuration) // 5. 存储新的refresh token s.storeRefreshToken(newRefreshTokenInfo) return newTokenString, nil } 2. 前端Http拦截器实现 请求拦截器 - 自动Token刷新 private httpInterceptorsRequest(): void { Http.axiosInstance.interceptors.request.use( async (config: HttpRequestConfig): Promise<any> => { // 请求白名单,不需要token的接口 const whiteList = ["/refreshToken", "/login", "/captcha/id", "/captcha/image"]; return whiteList.some(url => config.url?.includes(url)) ? config : new Promise(resolve => { const data = getAccessToken(); const refreshTokenData = getRefreshToken(); // 过期时间小于3秒时即认为过期 const expired = !data || data.accessTokenExpires * 1000 - Date.now() <= 3000; if (expired && refreshTokenData) { // 过期处理 - 自动刷新Token if (!Http.isRefreshing) { Http.isRefreshing = true; // token过期刷新 useUserStoreHook() .handRefreshToken(refreshTokenData.refreshToken) .then((res: any) => { const token = res.data.accessToken; if (config.headers) { config.headers["Authorization"] = formatToken(token); } Http.requests.forEach(cb => cb(token)); Http.requests = []; }) .finally(() => { Http.isRefreshing = false; }); } resolve(Http.retryOriginalRequest(config)); } else { // 未过期 - 正常添加Token if (config.headers && data?.accessToken) { config.headers["Authorization"] = formatToken(data.accessToken); } resolve(config); } }); } ); } 响应拦截器 - 错误处理 private httpInterceptorsResponse(): void { instance.interceptors.response.use( (response: HttpResponse) => { return response.data; }, (error: HttpError) => { const status = error.response?.status; const config = error.config; // 刷新token的API报错时提示跳转登录页 if (config?.url?.includes("/refreshToken")) { throttledModalConfirm({ title: '提示', content: '登录状态已过期,请重新登录', onOk: () => { Http.redirectLoginPage(); } }); } else if (status === 401) { // 401错误时,提示用户刷新页面重试 throttledModalConfirm({ title: '提示', content: '登录状态已过期,请刷新页面重试', onOk: () => { window.location.reload(); } }); } return Promise.reject(error); } ); } 3. 前端Auth工具类 Token存储管理 export interface AccessTokenData { accessToken: string; accessTokenExpires: number; // 时间戳 } export interface RefreshTokenData { refreshToken: string; refreshTokenExpires: number; // 时间戳 } // Token存储到Cookie export function setAccessToken(accessToken: string, accessTokenExpires: number) { const cookieString = JSON.stringify({ accessToken: accessToken, accessTokenExpires }); Cookies.set(AccessTokenKey, cookieString, { expires: (accessTokenExpires * 1000 - Date.now()) / 86400000 }); } export function setRefreshToken(refreshToken: string, refreshTokenExpires: number) { const cookieString = JSON.stringify({ refreshToken: refreshToken, refreshTokenExpires }); Cookies.set(RefreshTokenKey, cookieString, { expires: (refreshTokenExpires * 1000 - Date.now()) / 86400000 }); } // Token格式化 export const formatToken = (token: string): string => { return "Bearer " + token; }; 4. 后端JWT认证中间件 JWTAuthMiddleware func JWTAuthMiddleware() gin.HandlerFunc { return func(c *gin.Context) { // 1. 从Header获取Access Token tokenString, err := common.GetAccessToken(c) // 2. 验证Token有效性 claims, err := app.TokenService.ValidateTokenWithCache(tokenString) // 3. 将用户信息存储到上下文 c.Set(consts.BindContextKeyName, claims) // 4. 继续处理请求 c.Next() } } 5. 后端认证控制器 Login方法 func (ac *AuthController) Login(c *gin.Context) { // 1. 验证请求参数 var req models.LoginRequest req.Validate(c) // 2. 查询用户信息 user := models.NewUser() user.Find(c, func(d *gorm.DB) *gorm.DB { return d.Where("username = ?", req.Username).Preload("Tenant") }) // 3. 验证租户权限 tenantID, tenantCode := ac.validateTenant(user, req.TenantCode) // 4. 密码验证和登录锁定机制 ac.validatePassword(user, req.Password, req.Username) // 5. 生成令牌对 token, _ := app.TokenService.GenerateTokenWithCache(&app.ClaimsUser{ UserID: user.ID, Username: user.Username, TenantID: tenantID, TenantCode: tenantCode, }) refreshToken, _ := app.TokenService.GenerateRefreshToken(user.ID) // 6. 返回响应 ac.Success(c, gin.H{ "accessToken": token, "accessTokenExpires": claims.ExpiresAt.Unix(), "refreshToken": refreshToken, "refreshTokenExpires": claims1.ExpiresAt.Unix(), }) } RefreshToken方法 func (ac *AuthController) RefreshToken(c *gin.Context) { // 1. 获取Refresh Token refreshToken := c.GetHeader("RefreshToken") // 2. 解析Refresh Token获取用户ID claims, err := app.TokenService.ParseRefreshToken(refreshToken) // 3. 查询用户信息 var user models.User app.DB().WithContext(c).First(&user, claims.UserID) // 4. 刷新Access Token newAccessToken, err := app.TokenService.RefreshAccessTokenWithCache(refreshToken, &app.ClaimsUser{ UserID: user.ID, Username: user.Username, }) // 5. 轮换Refresh Token newRefreshToken, err := app.TokenService.RotateRefreshToken(refreshToken) // 6. 返回新的令牌对 ac.Success(c, gin.H{ "accessToken": newAccessToken, "accessTokenExpires": claims1.ExpiresAt.Unix(), "refreshToken": newRefreshToken, "refreshTokenExpires": newRefreshClaims.ExpiresAt.Unix(), }) } 配置管理 Token相关配置 token: jwttokensignkey: "gin-fast" # JWT签名密钥 jwttokenexpire: 43200 # Access Token过期时间(12小时),可配置 jwttokenrefreshexpire: 2592000 # Refresh Token过期时间(30天),可配置 cachekeyprefix: "gin-fast:" # 缓存前缀 isCache: false # 是否开启Access Token缓存 缓存配置 server: cachetype: "redis" # 缓存模式 memory OR redis 缓存策略 1. 缓存后端配置 系统支持两种缓存后端: Redis缓存 特点: 分布式、持久化、适合生产环境 配置: 通过Redis配置连接 适用场景: 多实例部署、高可用环境 内存缓存 特点: 高性能、单机、重启丢失 配置: 无需额外配置 适用场景: 开发环境、单机部署 2. Token缓存策略 Access Token缓存 可配置: 通过 isCache 配置控制是否缓存 缓存模式: 白名单模式,缓存中存在的Token才有效 优势: 支持立即Token撤销 性能: 缓存模式下性能略低,但安全性更高 Refresh Token缓存 强制缓存: Refresh Token一定会被缓存 存储方式: 每个用户只有一个有效的Refresh Token 优势: 支持Token轮换和立即撤销 3. 缓存键设计 Access Token Key func (s *TokenService) getTokenKeyWithCache(userID uint, tokenString string) string { hash := md5.Sum([]byte(tokenString)) tokenHash := fmt.Sprintf("%x", hash)[:8] return fmt.Sprintf("%stoken:%d:%s", s.CacheKeyPrefix, userID, tokenHash) } Refresh Token Key func (s *TokenService) getRefreshTokenKey(userID uint) string { return fmt.Sprintf("%srefresh_token:%d", s.CacheKeyPrefix, userID) } 安全特性 1. 登录锁定机制 safe: loginlockthreshold: 3 # 密码错误锁定阈值 loginlockexpire: 60 # 失败次数记录缓存时间 loginlockduration: 600 # 账号锁定时长 2. Token安全 JWT签名: 使用HS256算法 密钥配置: 通过配置文件管理 过期时间: 合理的过期时间设置 Token轮换: Refresh Token轮换机制 3. 租户隔离 Token中包含租户信息,实现多租户系统的权限隔离: type ClaimsUser struct { UserID uint `json:"userId"` Username string `json:"username"` TenantID uint `json:"tenantId,omitempty"` TenantCode string `json:"tenantCode,omitempty"` } TokenService使用灵活性 1. 独立调用模式 TokenService设计为独立的服务组件,开发者可以根据需要选择使用方式: 仅使用基础Token功能 // 仅生成和验证Access Token,不使用Refresh Token机制 token, err := app.TokenService.GenerateToken(user) claims, err := app.TokenService.ValidateToken(tokenString) 使用完整Token管理 // 使用完整的Token管理,包括Refresh Token token, err := app.TokenService.GenerateTokenWithCache(user) refreshToken, err := app.TokenService.GenerateRefreshToken(user.ID) newToken, err := app.TokenService.RefreshAccessTokenWithCache(refreshToken, user) 2. 缓存配置灵活性 Access Token缓存可选 开启缓存: 支持立即Token撤销,安全性更高 关闭缓存: 性能更高,但无法立即撤销Token 配置控制: 通过 isCache 配置项控制 Refresh Token强制缓存 必须缓存: 确保Refresh Token的安全管理 单用户单Token: 每个用户只有一个有效的Refresh Token 自动轮换: 支持Token轮换保持安全性 路由配置 公开路由(无需认证) public := api.Group("") public.POST("/login", middleware.CaptchaMiddleware(), authControllers.Login) public.POST("/refreshToken", authControllers.RefreshToken) 受保护路由(需要JWT认证) protected := api.Group("") protected.Use(middleware.JWTAuthMiddleware()) protected.Use(middleware.DemoAccountMiddleware()) protected.Use(middleware.CasbinMiddleware()) 前后端交互流程 1. 完整的Token生命周期 登录过程 Redis后端前端用户Redis后端前端用户输入用户名密码POST /login验证用户身份生成Access Token生成Refresh Token存储Refresh Token返回令牌对存储到Cookie登录成功 Token自动刷新过程 Redis后端前端Redis后端前端检测Token即将过期(3秒)POST /refreshToken验证Refresh Token生成新Access Token轮换Refresh Token更新Refresh Token返回新令牌对更新Cookie重试待处理请求 2. 错误处理机制 前端错误处理策略 Token刷新失败: 跳转登录页 401错误: 提示刷新页面 网络错误: 友好提示 重复刷新保护: 防止并发刷新 后端错误处理策略 Token无效: 返回401状态码 Refresh Token过期: 要求重新登录 租户权限不足: 返回403状态码 登录锁定: 返回429状态码 最佳实践 1. Token管理 前后端协同: 前端自动刷新,后端安全验证 双Token机制: Access Token(12h) + Refresh Token(30d) 智能过期检测: 前端提前3秒检测Token过期 Token轮换: 保持Refresh Token剩余有效期 2. 安全性 登录锁定: 防止暴力破解 多租户隔离: Token包含租户信息 Token撤销: 支持立即失效 白名单机制: 防止Token过期死循环 3. 性能优化 缓存模式可选: 平衡安全性和性能 请求队列: 防止重复刷新 节流控制: 防止频繁跳转登录页 高效验证: JWT签名验证 + 缓存检查 4. 用户体验 无感刷新: 用户无需手动操作 友好提示: 清晰的错误信息 状态保持: 刷新页面后保持登录状态 重试机制: 自动重试待处理请求 总结 GinFast项目的Token管理系统设计完善,具备以下特点: 后端优势 安全性高: 支持Token撤销、登录锁定、多租户隔离 灵活性好: 支持可配置的缓存模式(Redis/内存) 扩展性强: 清晰的接口设计和模块化架构 配置灵活: Token过期时间可配置,缓存策略可选 前端优势 用户体验佳: 提供Token自动刷新机制 错误处理完善: 多种错误场景的友好处理 性能优化: 请求队列和节流控制 前后端协同 完整生命周期: 从登录到登出的完整流程 智能刷新: 前端自动检测和刷新Token 状态同步: Cookie存储与后端验证同步 核心特性 缓存策略灵活: Access Token缓存可选,Refresh Token强制缓存 TokenService独立: 可单独调用基础功能或完整管理功能 多缓存后端: 支持Redis和内存两种缓存后端 配置驱动: 所有关键参数均可通过配置文件调整 该系统能够满足企业级应用的安全认证需求,为多租户SaaS应用提供了可靠的Token管理解决方案,实现了前后端无缝协作的安全认证体系。 关键源码文件 后端核心文件 app/utils/tokenhelper/tokenhelper.go - Token服务实现 app/middleware/jwt.go - JWT认证中间件 app/controllers/auth.go - 认证控制器 app/routes/routes.go - 路由配置 app/utils/cachehelper/ - 缓存实现(Redis和内存) 前端核心文件 src\\utils\\http\\index.ts - HTTP拦截器 src\\utils\\auth.ts - Token工具类

优秀的个人博客,低调大师

基于 Tailwind CSS + Shadcn 的 Vue3 后台管理模版 2024.0.6 发布

推荐一套为 Java 开发人员提供方便易用的 SDK 来与目前提供服务的的 Open AI 进行交互组件:https://github.com/devlive-community/openai-java-sdk 推荐一套功能强大的开源数据中台系统:https://github.com/devlive-community/datacap Shadcn UI Vue Admin 是一个使用 Shadcn UI (基于 Tailwind CSS) 和 Vite 和 Vue 制作的管理面板。在构建时考虑了响应能力和可访问性。 本次版本为公开版本,支持了Tree和Timeline模版功能。以下是该模版的目前支持的功能截图。 移除 Shadcn UI 原始代码优化启动编译方式 树形组件 树形组件自定义 Slot + 右键菜单 时间线组件 时间线组件 Milestone 时间线组件 Progress 时间线组件 Discussion 该模版的使用方式比较简单只要传递相应的数据即可,也支持多个 slot 用户自定义,欢迎大家使用。 推荐一套全平台数据库管理工具,建议下载使用:https://github.com/devlive-community/dbm 我们即将推出一套开源新系统。InfoSphere 是一款面向企业和个人的开源 Wiki 系统,旨在提供简单而强大的知识管理解决方案。建议尝试使用:https://github.com/devlive-community/incubator-infosphere 欢迎大家前往测试站点使用并提出宝贵的建议,如果您有需要实现的布局,可以提交 issues 我们会在最快的时间内实现。 我们的示例地址为:https://shadcn.vue.devlive.org/ive.org/

优秀的个人博客,低调大师

基于 Tailwind CSS + Shadcn 的 Vue3 后台管理模版 2024.0.5 发布

推荐一套为 Java 开发人员提供方便易用的 SDK 来与目前提供服务的的 Open AI 进行交互组件:https://github.com/devlive-community/openai-java-sdk 推荐一套功能强大的开源数据中台系统:https://github.com/devlive-community/datacap Shadcn UI Vue Admin 是一个使用 Shadcn UI (基于 Tailwind CSS) 和 Vite 和 Vue 制作的管理面板。在构建时考虑了响应能力和可访问性。 本次版本为公开版本,支持了两个Navbar模版功能。以下是该模版的目前支持的功能截图。 基础导航栏 携带 Topbar 导航栏 该模版的使用方式比较简单只要传递相应的数据即可,也支持多个 slot 用户自定义,欢迎大家使用。 推荐一套全平台数据库管理工具,建议下载使用:https://github.com/devlive-community/dbm 我们即将推出一套开源新系统。InfoSphere 是一款面向企业和个人的开源 Wiki 系统,旨在提供简单而强大的知识管理解决方案。建议尝试使用:https://github.com/devlive-community/incubator-infosphere 欢迎大家前往测试站点使用并提出宝贵的建议,如果您有需要实现的布局,可以提交 issues 我们会在最快的时间内实现。 我们的示例地址为:https://shadcn.vue.devlive.org/

优秀的个人博客,低调大师

基于 Tailwind CSS + Shadcn 的 Vue3 后台管理模版 2024.0.4 发布

推荐一套为 Java 开发人员提供方便易用的 SDK 来与目前提供服务的的 Open AI 进行交互组件:https://github.com/devlive-community/openai-java-sdk 推荐一套功能强大的开源数据中台系统:https://github.com/devlive-community/datacap Shadcn UI Vue Admin 是一个使用 Shadcn UI (基于 Tailwind CSS) 和 Vite 和 Vue 制作的管理面板。在构建时考虑了响应能力和可访问性。 本次版本为公开版本,支持了Chat,Footer功能。以下是该模版的目前支持的功能截图。 Chat (重构) Chat Resizable Footer Footer Modern 该模版的使用方式比较简单只要传递相应的数据即可,也支持多个 slot 用户自定义,欢迎大家使用。 推荐一套全平台数据库管理工具,建议下载使用:https://github.com/devlive-community/dbm 我们即将推出一套开源新系统。InfoSphere 是一款面向企业和个人的开源 Wiki 系统,旨在提供简单而强大的知识管理解决方案。建议尝试使用:https://github.com/devlive-community/incubator-infosphere 欢迎大家前往测试站点使用并提出宝贵的建议,如果您有需要实现的布局,可以提交 issues 我们会在最快的时间内实现。 我们的示例地址为:https://shadcn.vue.devlive.org/

优秀的个人博客,低调大师

基于 Tailwind CSS + Shadcn 的 Vue3 后台管理模版 2024.0.3 发布

推荐一套为 Java 开发人员提供方便易用的 SDK 来与目前提供服务的的 Open AI 进行交互组件:https://github.com/devlive-community/openai-java-sdk 推荐一套功能强大的开源数据中台系统:https://github.com/devlive-community/datacap Shadcn UI Vue Admin 是一个使用 Shadcn UI (基于 Tailwind CSS) 和 Vite 和 Vue 制作的管理面板。在构建时考虑了响应能力和可访问性。 本次版本为公开版本,支持了ICard,IButton功能。以下是该模版的目前支持的功能截图。 IButton ICard 后续会推出更多的布局结构,方便使用者开箱即用,在我们的模版中,用户只需要修改国际化文件,和提供服务的接口,即可在不做修改页面的前提下直接集成到项目中。 推荐一套全平台数据库管理工具,建议下载使用:https://github.com/devlive-community/dbm 我们即将推出一套开源新系统。InfoSphere 是一款面向企业和个人的开源 Wiki 系统,旨在提供简单而强大的知识管理解决方案。建议尝试使用:https://github.com/devlive-community/incubator-infosphere 欢迎大家前往测试站点使用并提出宝贵的建议,如果您有需要实现的布局,可以提交 issues 我们会在最快的时间内实现。 我们的示例地址为:https://shadcn.vue.devlive.org/

优秀的个人博客,低调大师

基于 Tailwind CSS + Shadcn 的 Vue3 后台管理模版 2024.0.2 发布

推荐一套为 Java 开发人员提供方便易用的 SDK 来与目前提供服务的的 Open AI 进行交互组件:https://github.com/devlive-community/openai-java-sdk 推荐一套功能强大的开源数据中台系统:https://github.com/devlive-community/datacap Shadcn UI Vue Admin 是一个使用 Shadcn UI (基于 Tailwind CSS) 和 Vite 和 Vue 制作的管理面板。在构建时考虑了响应能力和可访问性。 本次版本为公开版本,支持了表单,卡片等多种实用的模版功能,同时支持深色/浅色,国际化等功能。以下是该模版的目前支持的功能截图。 仪表盘 表单(基础表单) 表单(带操作功能表单) 表单(带分割字段的表单) 表单(带图片的表单) 表单(带第三方登录的表单) 表单(带校验的表单) 卡片(基础) 卡片(模拟 Git) 卡片(模拟团队) 国际化 消息通知 登录 注册 忘记密码 等等还有一些其他页面布局,后续会推出更多的布局结构,方便使用者开箱即用,在我们的模版中,用户只需要修改国际化文件,和提供服务的接口,即可在不做修改页面的前提下直接集成到项目中。 推荐一套全平台数据库管理工具,建议下载使用:https://github.com/devlive-community/dbm 我们即将推出一套开源新系统。InfoSphere 是一款面向企业和个人的开源 Wiki 系统,旨在提供简单而强大的知识管理解决方案。建议尝试使用:https://github.com/devlive-community/incubator-infosphere 欢迎大家前往测试站点使用并提出宝贵的建议,如果您有需要实现的布局,可以提交 issues 我们会在最快的时间内实现。 我们的示例地址为:https://shadcn.vue.devlive.org/

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册