601451f22b
Overlay ~150 upstream items onto our V8.12 base, preserving trade-pro
theme, registry tests, and design docs. Re-applied our patch set
(discovery/env_for/blocks.css/type-mapping/theme_color/frontend entries,
test_theme_pro_v3 mods) — all anchors survived upstream evolution.
New platform enhancement (fixes upgrade-introduced regression):
multilingual.site_locale now honors settings_json.locale, plus
PUT /api/i18n/sites/{id}/locale — standalone English sites get
<html lang='en'> under the V8.15 locale-rewrite pipeline.
compose: adopt V8.21.3 (image 8.21.3-dev.1, /api/ready probes, MySQL/S3
env) with project name pinned to siteforge-v8-10 (data volumes).
Tests: 356 passed / 11 failed — all 11 confirmed pre-existing in
pristine V8.21.3 on this host (10 upstream Windows env + our build test
now green after locale fix). Patch registry updated in plan doc.
Co-Authored-By: Claude Code <noreply@anthropic.com>
21 lines
3.9 KiB
Vue
21 lines
3.9 KiB
Vue
<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 {watch,onMounted,ref} from 'vue'
|
||
import {ElMessage,ElMessageBox} from 'element-plus'
|
||
import {preferredSite,rememberSite,sfApi} from './_shared'
|
||
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){return sfApi<any>(path,{method,headers:body===undefined?{}:{'Content-Type':'application/json'},body:body===undefined?undefined:JSON.stringify(body)})}
|
||
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)}}
|
||
watch(siteId,(id)=>rememberSite(id))
|
||
onMounted(async()=>{try{csrf.value=(await api('/api/auth/me')).csrf;sites.value=await api('/api/sites');siteId.value=preferredSite(sites.value);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>
|