From 73ab89d551fe72bf1c6ac0d5ff80cefbe4f1ffca Mon Sep 17 00:00:00 2001 From: qian Date: Fri, 12 Jun 2026 00:43:55 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E5=AE=8C=E5=96=84=E7=A7=9F=E6=88=B7?= =?UTF-8?q?=E7=AB=AF=E6=B3=A8=E5=86=8C=E6=97=B6=E7=9A=84=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E5=8D=8F=E8=AE=AE=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/tenant/v1/agreement.go | 4 +- internal/middleware/tenant_auth.go | 14 +++ web/admin/src/views/system/SettingsPage.vue | 2 + web/tenant/src/router/tenant.ts | 6 -- web/tenant/src/utils/request.ts | 2 +- web/tenant/src/views/auth/AgreementPage.vue | 108 -------------------- web/tenant/src/views/auth/LoginPage.vue | 31 +++++- web/tenant/src/views/auth/RegisterPage.vue | 59 ++++++----- 8 files changed, 79 insertions(+), 147 deletions(-) delete mode 100644 web/tenant/src/views/auth/AgreementPage.vue diff --git a/api/tenant/v1/agreement.go b/api/tenant/v1/agreement.go index 3bf893d..662f94d 100644 --- a/api/tenant/v1/agreement.go +++ b/api/tenant/v1/agreement.go @@ -35,7 +35,7 @@ type TenantAgreementAcceptRes struct{} // --- 公开端点(登录/注册页面使用,无需认证) --- type AgreementCurrentListReq struct { - g.Meta `path:"/agreements/current" method:"get" mime:"json" tags:"公开-用户协议" summary:"所有当前生效的协议列表" group:"public" middleware:"-"` + g.Meta `path:"/agreements/current" method:"get" mime:"json" tags:"公开-用户协议" summary:"所有当前生效的协议列表" middleware:"-"` } type PublicAgreementItem struct { @@ -52,7 +52,7 @@ type AgreementCurrentListRes struct { } type AgreementCurrentGetReq struct { - g.Meta `path:"/agreements/current/{code}" method:"get" mime:"json" tags:"公开-用户协议" summary:"按标识码获取当前协议详情" group:"public" middleware:"-"` + g.Meta `path:"/agreements/current/{code}" method:"get" mime:"json" tags:"公开-用户协议" summary:"按标识码获取当前协议详情" middleware:"-"` Code string `json:"code" in:"path" v:"required|length:1,50"` } diff --git a/internal/middleware/tenant_auth.go b/internal/middleware/tenant_auth.go index bc4d0fc..4138408 100644 --- a/internal/middleware/tenant_auth.go +++ b/internal/middleware/tenant_auth.go @@ -1,6 +1,8 @@ package middleware import ( + "strings" + "github.com/gogf/gf/v2/net/ghttp" "github.com/qianfree/team-api/internal/dao" @@ -21,6 +23,12 @@ var tenantPublicPaths = map[string]bool{ "/api/tenant/email/reset-password": true, "/api/tenant/members/join": true, "/api/tenant/members/invite-info": true, + "/api/tenant/agreements/current": true, +} + +// tenantPublicPrefixes lists path prefixes that skip JWT auth (for dynamic routes like /current/{code}). +var tenantPublicPrefixes = []string{ + "/api/tenant/agreements/current/", } // TenantAuth is JWT authentication middleware for tenant console. @@ -31,6 +39,12 @@ func TenantAuth(r *ghttp.Request) { r.Middleware.Next() return } + for _, prefix := range tenantPublicPrefixes { + if strings.HasPrefix(r.URL.Path, prefix) { + r.Middleware.Next() + return + } + } tokenStr := extractBearerToken(r) if tokenStr == "" { diff --git a/web/admin/src/views/system/SettingsPage.vue b/web/admin/src/views/system/SettingsPage.vue index 37d6e60..dcc864a 100644 --- a/web/admin/src/views/system/SettingsPage.vue +++ b/web/admin/src/views/system/SettingsPage.vue @@ -14,6 +14,7 @@ import ContentFilterTab from './settings/ContentFilterTab.vue' import ChannelTab from './settings/ChannelTab.vue' import StorageTab from './settings/StorageTab.vue' import DataGovernanceTab from './settings/DataGovernanceTab.vue' +import AgreementTab from './settings/AgreementTab.vue' interface SettingCategory { key: string @@ -34,6 +35,7 @@ const categoryMap: Record = { channel: ChannelTab, storage: StorageTab, data_governance: DataGovernanceTab, + agreement: AgreementTab, } const categories = ref([]) diff --git a/web/tenant/src/router/tenant.ts b/web/tenant/src/router/tenant.ts index 42a90ad..8de8845 100644 --- a/web/tenant/src/router/tenant.ts +++ b/web/tenant/src/router/tenant.ts @@ -32,12 +32,6 @@ const tenantRoutes: RouteRecordRaw[] = [ component: () => import('@/views/auth/ForgotPasswordPage.vue'), meta: { requiresAuth: false, title: '找回密码' }, }, - { - path: '/tenant/agreement/:code', - name: 'TenantAgreement', - component: () => import('@/views/auth/AgreementPage.vue'), - meta: { requiresAuth: false, title: '协议详情' }, - }, { path: '/tenant/join', name: 'TenantJoin', diff --git a/web/tenant/src/utils/request.ts b/web/tenant/src/utils/request.ts index 5e8e938..a67cf17 100644 --- a/web/tenant/src/utils/request.ts +++ b/web/tenant/src/utils/request.ts @@ -104,7 +104,7 @@ async function doRefresh(): Promise { return newTokens } -const PUBLIC_PATHS = ['/settings/', '/captcha', '/captcha/', '/auth/login', '/auth/register'] +const PUBLIC_PATHS = ['/settings/', '/captcha', '/captcha/', '/auth/login', '/auth/register', '/agreements/'] function isPublicPath(url?: string): boolean { if (!url) return false diff --git a/web/tenant/src/views/auth/AgreementPage.vue b/web/tenant/src/views/auth/AgreementPage.vue deleted file mode 100644 index b5e0ec9..0000000 --- a/web/tenant/src/views/auth/AgreementPage.vue +++ /dev/null @@ -1,108 +0,0 @@ - - - - - diff --git a/web/tenant/src/views/auth/LoginPage.vue b/web/tenant/src/views/auth/LoginPage.vue index b5fd48d..ac7018d 100644 --- a/web/tenant/src/views/auth/LoginPage.vue +++ b/web/tenant/src/views/auth/LoginPage.vue @@ -10,6 +10,7 @@ import Icon from '@/components/common/Icon.vue' import SlideCaptcha from '@/components/common/SlideCaptcha.vue' import Turnstile from '@/components/common/Turnstile.vue' import AgreementAcceptModal from '@/components/common/AgreementAcceptModal.vue' +import AgreementViewModal from '@/components/common/AgreementViewModal.vue' const router = useRouter() const route = useRoute() @@ -46,6 +47,15 @@ const accountInput = ref(null) // Pending agreements const showAgreements = ref(false) +// Agreement view modal +const showAgreementModal = ref(false) +const agreementModalCode = ref('') + +function openAgreement(code: string) { + agreementModalCode.value = code + showAgreementModal.value = true +} + function proceedAfterLogin() { const pending = authStore.pendingAgreements if (pending.length > 0) { @@ -360,6 +370,11 @@ async function handleOAuthLogin(provider: string) {
{{ loading ? '登录中...' : '登录' }} +

+ + · + +

@@ -452,6 +467,11 @@ async function handleOAuthLogin(provider: string) {
{{ loading ? '登录中...' : '登录' }} +

+ + · + +

@@ -494,11 +514,6 @@ async function handleOAuthLogin(provider: string) { 立即创建

-

- 服务条款 - · - 隐私政策 -

@@ -507,6 +522,12 @@ async function handleOAuthLogin(provider: string) { :agreements="authStore.pendingAgreements" @accepted="onAgreementsAccepted" /> + +