369 lines
9.0 KiB
Vue
369 lines
9.0 KiB
Vue
<template>
|
||
<div class="dev-page">
|
||
<div class="page-header">
|
||
<div>
|
||
<h2 class="page-title">💻 源码与仓库</h2>
|
||
<p class="page-desc">申请仓库访问权限,获取完整源代码,支持私有化部署与二次开发。</p>
|
||
</div>
|
||
<a-button type="primary" @click="navigateTo('/developer/git')">
|
||
🐙 去绑定 Git 账号
|
||
</a-button>
|
||
</div>
|
||
|
||
<div class="page-body">
|
||
<!-- 权限获取流程 -->
|
||
<div class="panel mb-5">
|
||
<div class="panel-header">
|
||
<span class="panel-title">🚦 仓库访问权限流程</span>
|
||
</div>
|
||
<div class="flow-steps">
|
||
<div
|
||
v-for="(step, i) in steps"
|
||
:key="step.title"
|
||
class="flow-step"
|
||
:class="{ active: i <= currentStep, done: i < currentStep }"
|
||
>
|
||
<div class="flow-step-icon">
|
||
<span v-if="i < currentStep">✓</span>
|
||
<span v-else>{{ i + 1 }}</span>
|
||
</div>
|
||
<div class="flow-step-content">
|
||
<div class="flow-step-title">{{ step.title }}</div>
|
||
<div class="flow-step-desc">{{ step.desc }}</div>
|
||
<a-button
|
||
v-if="step.action"
|
||
size="small"
|
||
:type="i === currentStep ? 'primary' : 'default'"
|
||
class="mt-2"
|
||
@click="navigateTo(step.actionTo!)"
|
||
>
|
||
{{ step.action }}
|
||
</a-button>
|
||
</div>
|
||
<div v-if="i < steps.length - 1" class="flow-connector" />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<a-row :gutter="[16, 16]">
|
||
<!-- 仓库列表 -->
|
||
<a-col :xs="24" :lg="16">
|
||
<div class="panel">
|
||
<div class="panel-header">
|
||
<span class="panel-title">📁 我的仓库</span>
|
||
<a-button size="small" type="link" @click="navigateTo('/developer/requests')">查看申请记录</a-button>
|
||
</div>
|
||
|
||
<div class="empty-state">
|
||
<div class="empty-icon">💻</div>
|
||
<div class="empty-title">暂无可访问的仓库</div>
|
||
<div class="empty-desc">完成仓库权限申请后,获批的仓库将在此处显示</div>
|
||
<a-space class="mt-4">
|
||
<a-button type="primary" @click="navigateTo('/developer/git')">绑定 Git 账号</a-button>
|
||
<a-button @click="navigateTo('/developer/requests')">申请记录</a-button>
|
||
</a-space>
|
||
</div>
|
||
</div>
|
||
</a-col>
|
||
|
||
<!-- 源码模块说明 -->
|
||
<a-col :xs="24" :lg="8">
|
||
<div class="panel">
|
||
<div class="panel-header">
|
||
<span class="panel-title">📦 源码包含模块</span>
|
||
</div>
|
||
<div class="module-list">
|
||
<div v-for="mod in modules" :key="mod.title" class="module-item">
|
||
<div class="module-icon" :class="mod.color">{{ mod.emoji }}</div>
|
||
<div class="module-info">
|
||
<div class="module-title">{{ mod.title }}</div>
|
||
<div class="module-desc">{{ mod.desc }}</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="panel mt-4">
|
||
<div class="panel-header">
|
||
<span class="panel-title">✅ 源码权益说明</span>
|
||
</div>
|
||
<ul class="rights-list">
|
||
<li v-for="right in rights" :key="right" class="rights-item">
|
||
<span class="rights-check">✓</span>
|
||
<span>{{ right }}</span>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</a-col>
|
||
</a-row>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
definePageMeta({ layout: 'developer' })
|
||
useHead({ title: '源码与仓库 - 开发者中心' })
|
||
|
||
// 当前所在步骤(0=未绑定Git,1=已绑定待申请,2=已申请待审核,3=已获权限)
|
||
const currentStep = ref(0)
|
||
|
||
const steps = [
|
||
{
|
||
title: '绑定 Git 账号',
|
||
desc: '在 Git 账号绑定页面填写你的 Gitea 用户名,用于后续加组操作。',
|
||
action: '前往绑定',
|
||
actionTo: '/developer/git',
|
||
},
|
||
{
|
||
title: '提交加组申请',
|
||
desc: '填写申请表单,说明你需要访问的仓库和用途,等待运营审核。',
|
||
action: '提交申请',
|
||
actionTo: '/developer/requests',
|
||
},
|
||
{
|
||
title: '运营审核处理',
|
||
desc: '运营人员将在 1-3 个工作日内完成审核,并将你加入对应 Git 组。',
|
||
action: null,
|
||
actionTo: null,
|
||
},
|
||
{
|
||
title: '获得仓库访问权限',
|
||
desc: '审核通过后,你可以通过 Gitea 克隆仓库,开始二次开发。',
|
||
action: null,
|
||
actionTo: null,
|
||
},
|
||
]
|
||
|
||
const modules = [
|
||
{ emoji: '🗂️', title: 'Nuxt 4 前端', desc: 'Vue 3 + TypeScript,完整 SSR 源码', color: 'blue' },
|
||
{ emoji: '⚙️', title: 'Java 后端', desc: 'Spring Boot 3,多租户 SaaS 架构', color: 'purple' },
|
||
{ emoji: '🤖', title: 'AI 模块', desc: 'OpenClaw 集成,RAG 知识库引擎', color: 'orange' },
|
||
{ emoji: '🚢', title: '部署脚本', desc: 'Docker Compose + CI/CD 流水线', color: 'green' },
|
||
]
|
||
|
||
const rights = [
|
||
'完整多租户 SaaS 源码',
|
||
'私有 Git 仓库,持续同步更新',
|
||
'无商用限制,可自由二次开发',
|
||
'支持私有化本地/云端部署',
|
||
'详细架构说明与部署文档',
|
||
]
|
||
</script>
|
||
|
||
<style scoped>
|
||
.dev-page { min-height: 100%; }
|
||
|
||
.page-header {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
justify-content: space-between;
|
||
padding: 24px 28px 16px;
|
||
border-bottom: 1px solid #f0f0f0;
|
||
gap: 16px;
|
||
}
|
||
|
||
.page-title {
|
||
font-size: 20px;
|
||
font-weight: 700;
|
||
color: rgba(0, 0, 0, 0.88);
|
||
margin: 0 0 4px;
|
||
}
|
||
|
||
.page-desc {
|
||
font-size: 14px;
|
||
color: rgba(0, 0, 0, 0.45);
|
||
margin: 0;
|
||
}
|
||
|
||
.page-body {
|
||
padding: 20px 24px 28px;
|
||
}
|
||
|
||
.panel {
|
||
background: #fff;
|
||
border: 1px solid #f0f0f0;
|
||
border-radius: 12px;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.panel-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 14px 18px;
|
||
border-bottom: 1px solid #f5f5f5;
|
||
}
|
||
|
||
.panel-title {
|
||
font-size: 14px;
|
||
font-weight: 600;
|
||
color: rgba(0, 0, 0, 0.85);
|
||
}
|
||
|
||
/* 流程步骤 */
|
||
.flow-steps {
|
||
display: flex;
|
||
padding: 20px 24px;
|
||
gap: 0;
|
||
overflow-x: auto;
|
||
}
|
||
|
||
.flow-step {
|
||
flex: 1;
|
||
min-width: 150px;
|
||
position: relative;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
text-align: center;
|
||
padding: 0 16px;
|
||
}
|
||
|
||
.flow-step-icon {
|
||
width: 36px;
|
||
height: 36px;
|
||
border-radius: 50%;
|
||
background: #f0f0f0;
|
||
color: rgba(0, 0, 0, 0.35);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 14px;
|
||
font-weight: 700;
|
||
flex-shrink: 0;
|
||
z-index: 1;
|
||
border: 2px solid #e8e8e8;
|
||
transition: all 0.2s;
|
||
margin-bottom: 10px;
|
||
}
|
||
|
||
.flow-step.active .flow-step-icon {
|
||
background: linear-gradient(135deg, #4f46e5, #7c3aed);
|
||
color: #fff;
|
||
border-color: transparent;
|
||
box-shadow: 0 4px 12px rgba(79, 70, 229, 0.35);
|
||
}
|
||
|
||
.flow-step.done .flow-step-icon {
|
||
background: #16a34a;
|
||
color: #fff;
|
||
border-color: transparent;
|
||
}
|
||
|
||
.flow-step-title {
|
||
font-size: 13px;
|
||
font-weight: 600;
|
||
color: rgba(0, 0, 0, 0.75);
|
||
margin-bottom: 4px;
|
||
}
|
||
|
||
.flow-step.active .flow-step-title {
|
||
color: #4f46e5;
|
||
}
|
||
|
||
.flow-step-desc {
|
||
font-size: 12px;
|
||
color: rgba(0, 0, 0, 0.4);
|
||
line-height: 1.5;
|
||
}
|
||
|
||
.flow-connector {
|
||
position: absolute;
|
||
top: 17px;
|
||
right: -50%;
|
||
width: 100%;
|
||
height: 2px;
|
||
background: #e8e8e8;
|
||
z-index: 0;
|
||
}
|
||
|
||
/* 空状态 */
|
||
.empty-state {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
padding: 48px 24px;
|
||
text-align: center;
|
||
}
|
||
|
||
.empty-icon { font-size: 48px; margin-bottom: 12px; }
|
||
.empty-title { font-size: 16px; font-weight: 600; color: rgba(0, 0, 0, 0.7); }
|
||
.empty-desc { font-size: 13px; color: rgba(0, 0, 0, 0.4); margin-top: 6px; }
|
||
|
||
/* 模块列表 */
|
||
.module-list {
|
||
padding: 12px 16px;
|
||
}
|
||
|
||
.module-item {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12px;
|
||
padding: 10px 0;
|
||
border-bottom: 1px solid #f9f9f9;
|
||
}
|
||
|
||
.module-item:last-child { border-bottom: none; }
|
||
|
||
.module-icon {
|
||
width: 36px;
|
||
height: 36px;
|
||
border-radius: 9px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 18px;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.module-icon.blue { background: #eff6ff; }
|
||
.module-icon.purple { background: #f5f3ff; }
|
||
.module-icon.orange { background: #fff7ed; }
|
||
.module-icon.green { background: #f0fdf4; }
|
||
|
||
.module-title {
|
||
font-size: 13px;
|
||
font-weight: 500;
|
||
color: rgba(0, 0, 0, 0.85);
|
||
}
|
||
|
||
.module-desc {
|
||
font-size: 12px;
|
||
color: rgba(0, 0, 0, 0.4);
|
||
margin-top: 2px;
|
||
}
|
||
|
||
/* 权益列表 */
|
||
.rights-list {
|
||
list-style: none;
|
||
margin: 0;
|
||
padding: 12px 18px;
|
||
}
|
||
|
||
.rights-item {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
padding: 7px 0;
|
||
font-size: 13px;
|
||
color: rgba(0, 0, 0, 0.72);
|
||
border-bottom: 1px solid #f9f9f9;
|
||
}
|
||
|
||
.rights-item:last-child { border-bottom: none; }
|
||
|
||
.rights-check {
|
||
width: 18px;
|
||
height: 18px;
|
||
flex-shrink: 0;
|
||
border-radius: 50%;
|
||
background: #dcfce7;
|
||
color: #16a34a;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 11px;
|
||
font-weight: 700;
|
||
}
|
||
</style>
|