Files
cms-SiteForge/integrations/art-design-pro/src/views/siteforge/ReleaseCenter.vue
T
浅念 8cea7dee20 chore: baseline V8.10.0-dev.1 with v8_workflows type-mapping fix and trade-pro spec
- SiteForge Enterprise V8.10.0-dev.1 upstream source (210 tests)
- Fix: v8_workflows._mapped_input now reads both 类型/分类 columns so WXR
  imports keep post/product types instead of collapsing to page
- Docs: trade-pro theme port spec (R3) and implementation plan

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-22 16:49:25 +08:00

19 lines
3.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template><section class="release-center"><h2>构建与发布中心</h2><p>构建先通过迁移与质量验收,再提交独立审批;通过后才能部署到预先配置的 HTTPS 环境。</p>
<el-card shadow="never"><el-space><el-select v-model="siteId" @change="reload" style="width:240px"><el-option v-for="s in sites" :label="s.name" :value="s.id" :key="s.id" /></el-select><el-button @click="reload" :loading="loading">刷新任务</el-button></el-space></el-card>
<el-card shadow="never" style="margin-top:16px"><template #header>构建版本</template><el-table :data="builds" max-height="360"><el-table-column prop="id" label="版本ID" min-width="170"/><el-table-column prop="status" label="状态" width="110"/><el-table-column prop="total_pages" label="页面数" width="90"/><el-table-column prop="created_at" label="生成日期" width="180"/><el-table-column label="操作" min-width="260"><template #default="{row}"><el-button link @click="review(row.id)">申请审批</el-button><el-button link type="primary" @click="deploy(row.id,'staging')">发布测试环境</el-button><el-button link type="danger" @click="deploy(row.id,'production')">正式发布</el-button></template></el-table-column></el-table></el-card>
<el-card shadow="never" style="margin-top:16px"><template #header>审批请求</template><el-table :data="requests"><el-table-column prop="build_id" label="构建ID"/><el-table-column prop="state" label="审批状态" width="150"/><el-table-column prop="requested_by" label="申请人"/><el-table-column label="操作"><template #default="{row}"><el-button v-if="row.state==='pending'" link @click="approve(row.id)">审核通过</el-button></template></el-table-column></el-table></el-card>
</section></template>
<script setup lang="ts">
import {onMounted,ref} from 'vue'
import {ElMessage,ElMessageBox} from 'element-plus'
interface Site{id:string;name:string}
const sites=ref<Site[]>([]),siteId=ref(''),builds=ref<any[]>([]),requests=ref<any[]>([]),loading=ref(false),csrf=ref('')
async function api(path:string,method='GET',body?:unknown){const res=await fetch(path,{method,headers:{...(method==='GET'?{}:{'Content-Type':'application/json','X-SiteForge-CSRF':csrf.value})},credentials:'same-origin',body:body===undefined?undefined:JSON.stringify(body)});const data=await res.json();if(!res.ok)throw Error(data.detail||'请求失败');return data}
async function reload(){if(!siteId.value)return;loading.value=true;try{[builds.value,requests.value]=await Promise.all([api(`/api/sites/${siteId.value}/builds`),api(`/api/factory/sites/${siteId.value}/release-requests`)])}catch(e:any){ElMessage.error(e.message)}finally{loading.value=false}}
async function review(id:string){try{const r=await api(`/api/factory/sites/${siteId.value}/release-requests`,'POST',{build_id:id});ElMessage.success('审批请求已建立:'+r.id);await reload()}catch(e:any){ElMessage.error(e.message)}}
async function approve(id:string){try{await ElMessageBox.confirm('审批人不能是申请人,是否批准?','审核发布');await api(`/api/factory/sites/${siteId.value}/release-requests/${id}/review`,'POST',{state:'approved'});ElMessage.success('审批完成');await reload()}catch(e:any){if(e!=='cancel')ElMessage.error(e.message)}}
async function deploy(build_id:string,target:'staging'|'production'){try{await ElMessageBox.confirm(`将构建版本 ${build_id} 部署到 ${target},确认目标环境已配置 HTTPS?`,'发布确认');await api(`/api/production/sites/${siteId.value}/deploy`,'POST',{build_id,target});ElMessage.success('远程部署接收端已确认发布')}catch(e:any){if(e!=='cancel')ElMessage.error(e.message)}}
onMounted(async()=>{try{csrf.value=(await api('/api/auth/me')).csrf;sites.value=await api('/api/sites');siteId.value=sites.value[0]?.id||'';await reload()}catch(e:any){ElMessage.error(e.message)}})
</script>
<style scoped>.release-center h2{font-size:24px;margin:0 0 8px}.release-center p{color:var(--el-text-color-secondary);margin:0 0 25px;font-size:13px}</style>