批次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:
@@ -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
|
||||
|
||||
@@ -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')
|
||||
},
|
||||
}
|
||||
|
||||
@@ -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?: {
|
||||
|
||||
Reference in New Issue
Block a user