批次4后续专项完成:D11清偿 + OCC方案B实施 + 部署参数 + D2诚实标注 + CI门禁

① D11 HTML 报告 RustFS 单源化(TECH_DEBT P2 清偿):可视化产物写任务临时目录后
   裸传报告键 html/reports/{filename}(文件名寻址),/html StaticFiles 挂载删除,
   新增 html_report_router 根路径代理(报告键→遗留 JSON 包装→本地卷兜底→404,
   防穿越);URL 形状 /html/{filename} 不变,持久化引用零迁移;celery 摘除
   html_data 卷,镜像不再烤入陈旧报告;顺带删除 get_stp_file_with_data 死数据块
② OCC 方案 B(D10 清偿):run_occ(op_name, payload) 契约 + 常驻工作进程池
   (occ_process_pool + occ_worker 操作注册表),超时/崩溃 terminate 换新补位、
   任务级超时 recover 整体重建,残留线程泄漏根治;TopoDS 不跨进程(generate_cavity
   分模 + 方案 STEP 持久化全在子进程内,返回 export_manifest);删除内存形状缓存链、
   CADExporter.export_mold_results、shape_loader(→ stp_materializer)
③ OCC 方案 A 部署参数:CELERY_CONCURRENCY / CELERY_MAX_TASKS_PER_CHILD 进
   Dockerfile.celery + compose + .env.example
④ D2 诚实标注:铝价响应带 source: "simulated",前端按来源渲染标注(原硬编码
   "上海期货交易所"属虚假声明),死代码 getAluminumPrice 删除
⑤ CI 门禁:.gitea/workflows/ci.yml 三 job(pytest / 前端构建含 vue-tsc /
   openapi 漂移检测)

接口变更三件套随批完成(openapi 76→77 paths + gen:api + 前端构建通过;方案 B
接口面零变化)。测试基线 143 passed, 0 skipped(新增 16 项)。文档六处同步。

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
2026-09-18 17:22:01 +08:00
parent 0e6b3b1811
commit e728dcd226
36 changed files with 1474 additions and 565 deletions
+15 -3
View File
@@ -9,9 +9,9 @@
<div class="card aluminum-price-card">
<div class="card-header">
<div class="card-title">
<span class="aluminum-icon">🪙</span> 铝金属价格 (SHFE)
<span class="aluminum-icon">🪙</span> 铝金属价格
</div>
<span class="aluminum-source">数据来源: 上海期货交易所 | 更新于 {{ aluminum.date }}</span>
<span class="aluminum-source">{{ aluminumSourceLabel }}</span>
</div>
<div class="aluminum-content">
<div class="aluminum-price-row">
@@ -78,7 +78,7 @@
</template>
<script setup lang="ts">
import { reactive, onMounted, nextTick, ref } from 'vue'
import { computed, reactive, onMounted, nextTick, ref } from 'vue'
import { useRouter } from 'vue-router'
import { apiRequest } from '@/shared/api'
import { Chart, registerables } from 'chart.js'
@@ -98,6 +98,8 @@ interface AluminumPrice {
low: number
prev_close: number
week_ago_price: number
// D2:数据来源声明——simulated 为模拟走势(参考数据,非实时行情)
source?: string
}
interface HistoryItem {
@@ -112,6 +114,7 @@ const aluminum = reactive({
change: 0,
change_percent: 0,
open: 0,
source: '',
high: 0,
low: 0,
prev_close: 0,
@@ -124,12 +127,21 @@ const formatAluminumPrice = (val: number | null) => {
return Math.round(val).toLocaleString('zh-CN')
}
// D2:来源标注以接口 source 字段为准,不再硬编码交易所名称——
// 此前显示"数据来源: 上海期货交易所"而数据实为模拟走势,属虚假来源声明
const aluminumSourceLabel = computed(() => {
if (aluminum.source === 'simulated') return '模拟数据 · 参考走势,非实时行情'
if (aluminum.source) return `数据来源: ${aluminum.source}`
return `更新于 ${aluminum.date}`
})
const loadAluminumPrice = async () => {
try {
const data = await apiRequest<AluminumPrice>('/api/aluminum-price/current')
aluminum.price = data.price
aluminum.unit = data.unit
aluminum.date = data.date
aluminum.source = data.source ?? ''
aluminum.change = data.change
aluminum.change_percent = data.change_percent
aluminum.open = data.open
-4
View File
@@ -403,8 +403,4 @@ export const moldinsightApi = {
body: JSON.stringify(data),
})
},
getAluminumPrice() {
return apiRequest<{ price: number; unit: string; updated_at: string }>('/api/aluminum-price/current')
},
}
+48
View File
@@ -666,6 +666,23 @@ export interface paths {
patch?: never;
trace?: never;
};
"/html/{filename}": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/** 读取 HTML 可视化报告 */
get: operations["get_html_report_html__filename__get"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/products": {
parameters: {
query?: never;
@@ -4538,6 +4555,37 @@ export interface operations {
};
};
};
get_html_report_html__filename__get: {
parameters: {
query?: never;
header?: never;
path: {
filename: string;
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Successful Response */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": unknown;
};
};
/** @description Validation Error */
422: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["HTTPValidationError"];
};
};
};
};
list_products_api_products_get: {
parameters: {
query?: {