feat: tenant-scoped routing and portal navigation

This commit is contained in:
2026-01-08 21:30:46 +08:00
parent f3aa92078a
commit 3e095c57f3
52 changed files with 1111 additions and 670 deletions

View File

@@ -101,8 +101,8 @@
<p class="text-lg text-slate-600 mb-12 max-w-lg mx-auto">您的入驻申请已成功提交平台将在 1-3 个工作日内完成审核审核结果将通过短信和系统通知发送给您</p>
<div class="flex justify-center gap-4">
<router-link to="/" class="px-8 py-3 bg-white border border-slate-300 text-slate-700 rounded-lg hover:bg-slate-50 font-medium">返回首页</router-link>
<router-link to="/me" class="px-8 py-3 bg-primary-600 text-white rounded-lg hover:bg-primary-700 font-medium">查看个人中心</router-link>
<router-link :to="tenantRoute('/')" class="px-8 py-3 bg-white border border-slate-300 text-slate-700 rounded-lg hover:bg-slate-50 font-medium">返回首页</router-link>
<router-link :to="tenantRoute('/me')" class="px-8 py-3 bg-primary-600 text-white rounded-lg hover:bg-primary-700 font-medium">查看个人中心</router-link>
</div>
</div>
@@ -111,7 +111,11 @@
<script setup>
import { ref, reactive, computed } from 'vue';
import { useRoute } from 'vue-router';
import { tenantPath } from '../../utils/tenant';
const route = useRoute();
const tenantRoute = (path) => tenantPath(path, route);
const step = ref(1);
const submitting = ref(false);
const fileInput = ref(null);

View File

@@ -228,9 +228,11 @@ import { computed, reactive, ref, onMounted } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import { commonApi } from '../../api/common';
import { creatorApi } from '../../api/creator';
import { tenantPath } from '../../utils/tenant';
const router = useRouter();
const route = useRoute();
const tenantRoute = (path) => tenantPath(path, route);
const toast = useToast();
const fileInput = ref(null);
const currentUploadType = ref('');
@@ -499,7 +501,7 @@ const saveContent = async (targetStatus) => {
toast.add({ severity: 'success', summary: targetStatus === 'draft' ? '保存成功' : '发布成功', detail: targetStatus === 'draft' ? '已保存为草稿' : '内容已提交审核', life: 3000 });
}
setTimeout(() => router.push('/creator/contents'), 1500);
setTimeout(() => router.push(tenantRoute('/creator/contents')), 1500);
} catch (e) {
toast.add({ severity: 'error', summary: '操作失败', detail: e.message, life: 3000 });
} finally {

View File

@@ -2,7 +2,7 @@
<div>
<div class="flex items-center justify-between mb-8">
<h1 class="text-2xl font-bold text-slate-900">内容管理</h1>
<router-link to="/creator/contents/new"
<router-link :to="tenantRoute('/creator/contents/new')"
class="px-6 py-2.5 bg-primary-600 text-white rounded-lg font-bold hover:bg-primary-700 transition-colors shadow-sm shadow-primary-200 cursor-pointer active:scale-95 flex items-center gap-2">
<i class="pi pi-plus"></i> 发布新内容
</router-link>
@@ -83,7 +83,7 @@
</div>
<h3 class="text-slate-900 font-bold mb-1">暂无内容</h3>
<p class="text-slate-500 text-sm mb-6">您还没有发布任何内容快去创作吧</p>
<router-link to="/creator/contents/new" class="px-5 py-2 bg-primary-600 text-white rounded-lg text-sm font-bold hover:bg-primary-700 transition-colors">
<router-link :to="tenantRoute('/creator/contents/new')" class="px-5 py-2 bg-primary-600 text-white rounded-lg text-sm font-bold hover:bg-primary-700 transition-colors">
立即发布
</router-link>
</div>
@@ -100,7 +100,7 @@
class="w-full h-full object-cover">
<div
class="absolute inset-0 bg-black/50 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity">
<router-link :to="`/creator/contents/${item.id}`"
<router-link :to="tenantRoute(`/creator/contents/${item.id}`)"
class="text-white text-xs font-bold border border-white px-3 py-1 rounded hover:bg-white hover:text-black transition-colors">编辑</router-link>
</div>
</div>
@@ -119,7 +119,7 @@
class="bg-blue-50 text-blue-600 text-[11px] px-2 py-0.5 rounded-full font-bold whitespace-nowrap">{{
item.key }}</span>
<h3 class="font-bold text-slate-900 text-lg truncate hover:text-primary-600 cursor-pointer transition-colors"
@click="$router.push(`/creator/contents/${item.id}`)">
@click="$router.push(tenantRoute(`/creator/contents/${item.id}`))">
{{ item.title }}</h3>
</div>
<!-- Status Badge -->
@@ -170,7 +170,7 @@
<!-- Actions -->
<div class="flex items-center gap-4 pt-3 border-t border-slate-50 mt-3">
<button class="text-sm text-slate-500 hover:text-primary-600 font-medium cursor-pointer flex items-center gap-1"
@click="$router.push(`/creator/contents/${item.id}`)">
@click="$router.push(tenantRoute(`/creator/contents/${item.id}`))">
<i class="pi pi-file-edit"></i> 编辑
</button>
<button v-if="item.status === 'published'"
@@ -211,13 +211,17 @@
<script setup>
import { onMounted, ref, watch } from 'vue';
import { useRouter } from 'vue-router';
import { useRoute, useRouter } from 'vue-router';
import { useToast } from 'primevue/usetoast';
import { useConfirm } from 'primevue/useconfirm';
import ConfirmDialog from 'primevue/confirmdialog';
import Paginator from 'primevue/paginator';
import { commonApi } from '../../api/common';
import { creatorApi } from '../../api/creator';
import { tenantPath } from '../../utils/tenant';
const route = useRoute();
const tenantRoute = (path) => tenantPath(path, route);
const router = useRouter();
const toast = useToast();
@@ -407,4 +411,4 @@ const handleDelete = (id) => {
}
});
};
</script>
</script>

View File

@@ -3,7 +3,7 @@
<div class="flex items-center justify-between mb-8">
<h1 class="text-2xl font-bold text-slate-900">管理概览</h1>
<div class="flex gap-4">
<router-link to="/creator/contents/new"
<router-link :to="tenantRoute('/creator/contents/new')"
class="px-6 py-2.5 bg-primary-600 text-white rounded-lg font-bold hover:bg-primary-700 transition-colors shadow-sm shadow-primary-200 cursor-pointer active:scale-95 flex items-center gap-2">
<i class="pi pi-plus"></i> 发布新内容
</router-link>
@@ -39,7 +39,7 @@
<div class="flex gap-4">
<div
class="flex-1 p-4 bg-orange-50 border border-orange-100 rounded-xl flex items-center justify-between cursor-pointer hover:bg-orange-100 transition-colors"
@click="$router.push('/creator/orders')">
@click="$router.push(tenantRoute('/creator/orders'))">
<div class="flex items-center gap-3">
<div class="w-10 h-10 rounded-full bg-orange-200 text-orange-700 flex items-center justify-center"><i
class="pi pi-refresh"></i></div>
@@ -83,7 +83,7 @@
<div class="text-xs text-slate-500" v-if="hasPayoutAccount">已绑定{{ payoutAccounts[0].name }} ({{ payoutAccounts[0].account.slice(-4) }})</div>
<div class="text-xs text-orange-600 font-bold flex items-center gap-1" v-else>
<i class="pi pi-exclamation-circle"></i> 未配置收款账户
<router-link to="/creator/settings"
<router-link :to="tenantRoute('/creator/settings')"
class="underline hover:text-orange-800 ml-1">去配置</router-link>
</div>
</div>
@@ -134,8 +134,12 @@ import Dialog from 'primevue/dialog';
import Toast from 'primevue/toast';
import { useToast } from 'primevue/usetoast';
import { ref, onMounted, computed } from 'vue';
import { useRoute } from 'vue-router';
import { creatorApi } from '../../api/creator';
import { tenantPath } from '../../utils/tenant';
const route = useRoute();
const tenantRoute = (path) => tenantPath(path, route);
const toast = useToast();
const showWithdraw = ref(false);
const withdrawMethod = ref('wallet');
@@ -207,4 +211,4 @@ const handleWithdraw = async () => {
toast.add({ severity: 'error', summary: '提现失败', detail: '请稍后重试', life: 3000 });
}
};
</script>
</script>