恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

PHAST-SAFETI二次开发教程(16):数据对接——Phast API / Phast Web Services 与 PyPWS

  • 首页
  • 资讯中心
  • /
  • PHAST-SAFETI二次开发教程(16):数据对接——Phast API / Phast Web Services 与 PyPWS

相关资讯

Blazor Admin 关联表怎么处理?Navigate、Include、Join 实战 2026/10/8 19:32:23
基于springboot宠物领养系统-计算机毕设 附源码【课程设计】94217 2026/10/8 19:27:22
DeepSeek-R1 模型架构拆解:从 MoE 到推理链路的工程视角 2026/10/8 19:27:22

最新资讯

Python模拟Ethernet帧发送:从拼帧到CRC校验全解析
Ubuntu 24.04部署MySQL/Redis/Nginx与自动备份全记录
ThinkPHP与Laravel开发微信小程序美妆商城:选型、落地与踩坑全记录
Mac mini打造B站24小时AI评论助理实战指南
Spring Boot + Vue教室图书馆预约系统:从需求到部署全解析
虚拟机创建到配置全攻略:从选型到踩坑排查

今日推荐

context-mode实战指南:从全量塞入到结构化裁剪与检索增强
大模型对话上下文管理实战:三种模式与Token优化
抖音用户主页视频数据爬虫详解:点赞、收藏、分享字段抓取与 TaoToken 统一 Key 配置

本周热门

MR25H40CDF + PIC18F65K40:工业记录仪高可靠存储实战
基于STM32的数控恒压恒流电源设计:从硬件到PID调参全解析
LT9211 MIPI重定时器原理与双路扇出实战指南

本月精选

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)

PHAST-SAFETI二次开发教程(16):数据对接——Phast API / Phast Web Services 与 PyPWS

发布时间:2026/10/8 19:32:23
PHAST-SAFETI二次开发教程(16):数据对接——Phast API / Phast Web Services 与 PyPWS PHAST-SAFETI二次开发教程16数据对接——Phast API / Phast Web Services 与 PyPWS版本声明块工具/软件Phast™ / Safeti™版本主线 9.x具体以官方发布说明为准Phast API 官方托管服务 Build20260820.1以官方门户当前显示为准语言/环境Python ≥ 3.11PyPWS 官方要求官方客户端形态 Excel / Python / .NET / TypeScript 四选一即可本文目标搞清楚官方 API 的形态、端点、令牌与 PyPWS 的包结构并写出第一个能判定成功与失败的最小计算一句话结论Phast™ 的官方二次开发入口不是本地 SDK而是托管的 Phast Web ServicesREST端点https://phastwebservices.dnv.com/api/analytics/v1/ 四种官方客户端Excel / Python / .NET / TypeScriptPython 侧的官方库是PyPWSPyPI 包名小写pypws它的公开结构是pypws.calculations/pypws.entities/pypws.enums/pypws.utilities/pypws.constants/pypws.materials六个模块而判断一次计算是否成功靠的是calculation.run()返回的ResultCode是否为ResultCode.SUCCESS。本篇铁律适用三级标注取自系列登记的 10 条[硬约束] 铁律 2 闭源事实纪律本篇出现的每个类名/方法名/端点都必须能回溯官方来源无官方证据的一律标注「未确证 / 以官方文档为准」不臆造。[硬约束] 铁律 3 只用官方接口二次开发仅走 DNV 官方 Phast API / Phast Web Services / PyPWS不引入来源不明的第三方封装。[硬约束] 铁律 5 令牌与许可不硬编码access token 只从环境变量或密钥管理读取绝不写进脚本与仓库。[强约束] 铁律 4 单位与坐标系纪律Phast Web Services 全程SI 单位换算点必须集中在入参边界与出参边界。[提示] 铁律 10 能力边界不越界官方明列的可编程形态是 Web Services 四种客户端库COM / SDK 形态未确证正文不作主张。〇、本篇要解决的认知问题Phast API / Phast Web Services 的官方形态到底是什么与「本地装一个 SDK」有什么本质区别官方明列的四种客户端Excel / Python / .NET / TypeScript分别适合谁能不能共享同一套计算语义端点https://phastwebservices.dnv.com/api/analytics/v1/与 access token 是什么关系token 应该放在哪里PyPWS 的内部结构是怎么组织的六个模块各装什么动手时先看哪一个一次计算怎么判成功ResultCode与print_messages()在诊断链条里各扮演什么角色为什么 Phast Web Services 全程 SI 单位对接实践里最容易在什么地方把单位丢掉以下「认知问题回显FAQ」与上列问题一一对应、同序作答。一、机制解析1.1 官方形态托管 REST 服务 四种官方客户端必须先纠正一个常见误解Phast™ 的官方二次开发能力不是一个装在本地、可以随意import的 COM 组件或原生 SDK。官方门户phastwebservices.dnv.com明确给出的形态是一组托管的 Web API门户标题即用 “APIs”并同时明列四种官方客户端形态官方客户端形态载体典型使用者计算语义是否同源Excel官方 Excel 客户端工艺安全工程师、报表型作业同源同一托管计算Python官方 Python 库PyPWS自动化脚本、数据工程师同源.NET官方 .NET 客户端企业内部工具、桌面系统集成同源TypeScript官方 TypeScript 客户端Web 应用、数字孪生前端同源四种客户端不是四套模型而是同一套托管计算内核的四个翻译层。这一点有很强的工程含义用 PyPWS 跑出的结果与用 .NET 客户端跑同一组输入应当一致如果出现差异问题通常在输入装配或单位换算而不在「模型不一样」。按未确证项 B 的登记COM / Scripting 独立接口未确证。因此在本系列中任何「注册一个 COM 对象然后调用 Phast」的写法都不予采用。1.2 一次调用的生命周期① 客户端Excel / Python / .NET / TypeScript │ 计算请求物料 源项 气象 结果选项全部 SI ▼ ② Phast Web Services托管 端点 https://phastwebservices.dnv.com/api/analytics/v1/ │ 鉴权access token须向 DNV 获取 ▼ ③ Phast 后果计算内核与桌面 Phast™ 同源的模型链 │ 结果状态 / 泄漏 / 火灾 / 辐射断线 等结果对象 ▼ ④ 结果对象回传客户端 ├── ResultCode ──▶ 成功/失败硬判定 └── print_messages() ──▶ 诊断域消息失败时的唯一线索这张图里最值得记住的一句是鉴权在网络层判定在结果层。token 错了会在第②步就失败通常是连接/授权类错误脚本里看不到任何ResultCode而 token 正确但输入不合法时请求能到达第③步最终以一个非SUCCESS的ResultCode回到脚本。两种失败的排查路径完全不同这也是第三节报错排查的分叉点。1.3 PyPWS 的包结构PyPWS 是官方 Python 库文档体例写PyPWSPyPI 包名小写pypws官方要求 Python ≥ 3.11。它的公开模块按下表组织模块装什么什么时候看pypws.calculations计算对象如VesselStateCalculation/VesselLeakCalculation/JetFireCalculation/RadiationTransectCalculation每个场景的主入口pypws.entities输入实体如Material/MaterialComponent/State/Vessel/Leak/Weather/Substrate装配输入pypws.enums枚举如ResultCode/FluidSpec/VesselShape/VesselConditions/TimeVaryingOption/FlashAtOrifice/AtmosphericStabilityClass/SurfaceType/PoolSurfaceType/PoolFireType/RadiationType/ContourType/Resolution约束取值、避免拼写漂移pypws.utilities工具函数如getAnalyticsApiTarget()环境自检pypws.constants常量物理常量、默认值等避免自造常数铁律 8pypws.materials物料库函数如getAllCasIds()/getMaterialByCasId(casId)/getDNVComponents()/getDIPPRComponents()/getUserComponents()/getComponentById(id)/getComponentByName(name)/getComponentByCasId(casId)/storeMaterialComponent(...)/storeMaterialComponentAndCreateMaterial(...)选物料、建自定义物料工程习惯先utilities自检再materials选料再entities装配最后calculations跑。四步顺序反过来写先跑再查物料会在批量作业里浪费大量网络往返。关于pypws-cli依未确证项 I 的登记卸载输出中出现过pypws-cli但其完整命令范围未见官方文档正文仅承认其存在细节以官方文档为准。1.4 结果对象与 ResultCodePyPWS 的运行接口是一条极简契约calculation.run()返回ResultCode成功判据是与ResultCode.SUCCESS比较另有print_messages()用于打印诊断消息。已登记的结果属性包括outputState、material、vesselConditions、dischargeRecords等——这些是下游取数的接口面VesselStateCalculation.run() ──▶ ResultCode outputState │下游取数 ▼ VesselLeakCalculation ──▶ ResultCode dischargeRecords泄漏记录 │下游取数 ▼ JetFireCalculation / RadiationTransectCalculation ──▶ ResultCode 后果结果注意「下游取数」这四个字链路里每一环的结果属性同时是下一环的输入。因此判成败不能只看最后一环——如果上一环run()返回了非SUCCESS下游即使返回SUCCESS也可能是基于残缺输入算出的无意义值。这是批量作业里最隐蔽的一类错误第三节会给出对应的门禁写法。1.5 单位与数据交换纪律Phast Web Services全程 SI 单位铁律 4。工程上把换算集中到两个边界边界动作反例应避免入参边界把工程单位/现场单位一次性换算为 SI在装配函数里散落乘除系数出参边界把 SI 结果换算为报告单位并同时保留 SI 原值只留报告单位回归时无法与官方 SI 对账数据集层面跨客户端交换建议统一用**扁平表CSV/JSON**并显式带上units列不要依赖列名暗示单位。原因很实际Excel 客户端与 Python 客户端之间交换的往往就是这种扁平表一旦单位靠列名暗示第一次被别的同事改列名就崩了。二、完整操作与脚本逐段剖析构造参数与属性名声明以下代码用到pypws的类名/函数名/枚举成员均取自官方公开来源但各实体的构造参数签名与部分结果属性名会随版本演进一律以官方 PyPWS 参考文档官方 PDFPyPws.pdf为准。读者照抄前应先核对当前版本文档。2.1 第一段环境自检与端点确认# -*- coding: utf-8 -*-# 演示PyPWS 环境自检 —— Python 版本、库版本与当前 API 目标端点importsys# 标准库解释器信息importimportlib.metadataasmd# 标准库读取已安装包版本frompypws.utilitiesimportgetAnalyticsApiTarget# 官方工具返回当前 API 目标REQUIRED_PYTHON(3,11)# PyPWS 官方要求 Python 3.11assertsys.version_info[:2]REQUIRED_PYTHON,\PyPWS 要求 Python 3.11当前为 %s%..join(map(str,sys.version_info[:3]))try:pypws_versionmd.version(pypws)# 注意包名是小写 pypwsexceptmd.PackageNotFoundError:# 未安装分支pypws_version未安装修复pip install pypws# 给读者可执行的修复提示targetgetAnalyticsApiTarget()# 打印当前 API 目标端点print(Python :,sys.version.split()[0])# 解释器版本print(pypws :,pypws_version)# 官方库版本检索期为 4.2.25print(API目标 :,target)# 应指向 phastwebservices 域# —— 硬门禁端点必须落在官方托管域防止被环境变量指到测试/第三方地址 ——assertphastwebservicesinstr(target),API 目标异常请检查环境配置铁律 3这段是整篇最便宜的一次自检三行输出就能回答「我的库对不对、我的端点对不对」。把assert写成硬门禁而不是print提示是因为在 CI 里print只会留下日志而assert会直接阻断流水线。2.2 第二段最小可用计算容器状态 → 容器泄漏# -*- coding: utf-8 -*-# 演示最小可用链路 VesselStateCalculation - VesselLeakCalculationimportos# 标准库读取环境变量frompypws.calculationsimportVesselStateCalculation,VesselLeakCalculation# 计算类frompypws.entitiesimportMaterial,MaterialComponent,State,Vessel,Leak# 输入实体frompypws.enumsimportResultCode,FluidSpec,VesselShape,VesselConditions# 枚举# —— 令牌治理只从环境变量读取绝不硬编码铁律 5——TOKENos.environ.get(DNV_PWS_TOKEN)# 由密钥管理注入的环境变量assertTOKEN,缺少环境变量 DNV_PWS_TOKENaccess token 不得写入脚本或仓库# —— ① 物料装配单组元丙烷构造参数签名以官方 PyPWS 参考文档为准——componentMaterialComponent(namePROPANE,mole_fraction1.0)# 单个组元及其摩尔分数materialMaterial(namePROPANE-100,components[component])# 组物料# —— ② 滞止/容器状态SIK、Pa——stagnation_stateState(temperature298.15,# 298.15 K 25 ℃SIpressure1.0e6)# 1.0e6 Pa 10 barSI# —— ③ 容器与泄漏几何SIm——vesselVessel(vessel_shapeVesselShape.HORIZONTAL_CYLINDER,# 容器型式枚举fluid_specFluidSpec.GAS,# 相态说明枚举vessel_conditionsVesselConditions.INSULATED)# 容器条件枚举leakLeak(hole_diameter0.02)# 泄漏孔径 0.02 mSI# —— ④ 上游容器状态计算 ——state_calcVesselStateCalculation(materialmaterial,# 输入物料statestagnation_state,# 输入状态vesselvessel)# 输入容器state_codestate_calc.run()# 运行返回 ResultCodeprint(VesselStateCalculation:,state_code)# 打印结果码ifstate_code!ResultCode.SUCCESS:# 成功判定state_calc.print_messages()# 失败时打印诊断消息raiseSystemExit(上游状态计算失败下游不再执行避免基于残缺输入)# —— ⑤ 下游容器泄漏计算取上游 outputState 作为输入下游取数——leak_calcVesselLeakCalculation(materialmaterial,# 同一物料statestate_calc.outputState,# 关键接入上游结果属性leakleak)# 泄漏几何leak_codeleak_calc.run()# 运行print(VesselLeakCalculation:,leak_code)# 打印结果码ifleak_code!ResultCode.SUCCESS:# 同样硬判定leak_calc.print_messages()# 打印诊断raiseSystemExit(泄漏计算失败)print(泄漏记录条数,len(leak_calc.dischargeRecords))# 结果属性取数以官方文档为准这二十来行里有三个必须内化的动作。第一上游失败即中止state_code ! ResultCode.SUCCESS时直接raise SystemExit不让下游拿着残缺的outputState继续跑。第二诊断只在失败时打印print_messages()是失败时的唯一线索成功时打印只会污染日志。第三outputState显式接链statestate_calc.outputState这一行就是「模型链路」在代码里的样子它与第 05 篇讲的 Discharge→Dispersion→Effects 链路是同一件事在 API 层的投影。2.3 第三段结果读取与结构化落盘# -*- coding: utf-8 -*-# 演示把单场景结果抽成以 case_id 为键的长表便于与工况表 JOIN铁律 6importcsv# 标准库importhashlib# 标准库稳定唯一键defmake_case_id(payload:dict)-str:由输入维度生成稳定唯一键同工况同号是幂等与断点续跑的前提。raw|.join([# 竖线拼接避免歧义payload[material],# 物料名format(payload[pressure],.3f),# 压力Pa定长格式化format(payload[hole_diameter],.6f),# 孔径m定长格式化])returnhashlib.sha1(raw.encode(utf-8)).hexdigest()[:12]# 取前 12 位够用且可读defharvest_single(case_id:str,leak_calc:object)-list:把一次泄漏计算的记录抽成长表行case_id / metric / value / unit。rows[]# 长表容器forindex,recordinenumerate(leak_calc.dischargeRecords):# 逐条泄漏记录rows.append({case_id:case_id,# 幂等键可 JOIN 工况表metric:discharge_record_%d%index,# 记录序号作为指标名value:record,# 记录本体以官方文档结构为准unit:SI,# 单位纪律原值保持 SI})returnrows PAYLOAD{material:PROPANE-100,pressure:1.0e6,hole_diameter:0.02}# 示例输入CASE_IDmake_case_id(PAYLOAD)# 计算唯一键print(case_id ,CASE_ID)# 打印键便于对账# —— 装配好 leak_calc 之后省略构造见 2.2 段——# LONG_ROWS harvest_single(CASE_ID, leak_calc)LONG_ROWS[]# 占位无运行时保持脚本可解析withopen(pypws_results_long.csv,w,newline,encodingutf-8-sig)asfh:writercsv.DictWriter(fh,fieldnames[case_id,metric,value,unit])writer.writeheader()# 表头forrowinLONG_ROWS:# 逐行写出writer.writerow(row)print(长表行数,len(LONG_ROWS))# 回收规模确认case_id的构造与第 08 篇的批量纪律完全一致——这不是重复而是同一套幂等契约在 API 侧的延续无论数据来自 GUI 批处理还是 PyPWS键的构造规则必须统一否则两批结果无法合并。2.4 第四段多客户端协同与令牌脱敏# -*- coding: utf-8 -*-# 演示多客户端协同的产物约定 令牌脱敏打印importos# 标准库CLIENT_MATRIX[# 四客户端分工建议表{client:Excel,role:工程师手工核对与交付,artifacts:xlsx},{client:Python,role:自动化流水线,artifacts:csv/json},{client:.NET,role:企业内部工具集成,artifacts:app},{client:TypeScript,role:Web/数字孪生前端,artifacts:json},]foriteminCLIENT_MATRIX:# 逐行打印分工建议print(%-10s %-24s - %s%(item[client],item[role],item[artifacts]))defmasked(token:str)-str:令牌脱敏只保留头 4 位与长度便于排查「取到没有」而不泄露。ifnottoken:# 空值分支return未设置returntoken[:4]**max(0,len(token)-4)# 其余全部打码TOKENos.environ.get(DNV_PWS_TOKEN)# 从环境变量读取print(token ,masked(TOKEN))# 只打印脱敏值铁律 5保留masked()这种小工具很值调试期最常见的两类问题——「环境变量没注入」与「token 过期」——都能靠脱敏打印快速区分而不会把凭据写进日志。三、常见报错与排查现象 1脚本在run()之前就抛连接/授权类异常完全看不到ResultCode。根因鉴权发生在网络层token 缺失、失效或未注入到运行环境请求根本没到达计算内核。解法先用 2.1 段确认端点再用 2.4 段的masked()确认 token 是否被取到token 一律通过环境变量或密钥管理注入铁律 5不在代码里传参。现象 2run()返回非SUCCESS但脚本没有输出任何有用信息。根因只判断了结果码没有调用print_messages()诊断消息域是失败时的唯一线索。解法在每次run()后紧跟「非SUCCESS即print_messages()」的两行模式见 2.2 段把诊断固化进代码模板。现象 3下游计算返回SUCCESS但结果数量级明显不合理。根因上游run()实际失败脚本仍把outputState传给了下游下游基于残缺输入算出了「成功但无意义」的结果。解法链路每一环都做成功判定上游失败即中止见 2.2 段的raise SystemExit并把「上游结果码」一并记入结果表。现象 4报「参数名未知 / 未知关键字参数」。根因实体构造参数签名随版本演进照抄了旧版本示例。解法以官方 PyPWS 参考文档PyPws.pdf为准核对当前版本的构造签名把逐篇示例视为「结构参考」而非「签名权威」。现象 5结果数值与桌面 GUI 差一个众所周知的比例如 14.5 / 1000 / 3600。根因单位换算点散落某个输入仍带着工程单位bar、mm、℃、t/h进入了 SI 的世界。解法把换算集中在入参边界与出参边界两处1.5 节的表在结果表里同时保留 SI 原值与报告单位便于对账铁律 4。现象 6物料在库中找不到或名称拼写与库中不一致。根因pypws.materials的检索函数需要按 CAS 号或组件 ID/名称查找名称字符串不匹配时查不到。解法优先用getComponentByCasId(casId)或getMaterialByCasId(casId)按 CAS 号定位唯一性强于名称需要建自定义物料时用storeMaterialComponent(...)/storeMaterialComponentAndCreateMaterial(...)并把物料来源登记入库铁律 9 的可追溯思路。四、动手练习把 2.1 段的自检脚本改成「无assert版」人为把端点指向一个错误域名对比两种写法在 CI 中的行为差异。用pypws.materials的getAllCasIds()列出可用物料编号再用getMaterialByCasId(casId)取回其中一个打印其组件信息。把 2.2 段的链路扩展一环在VesselLeakCalculation之后接入JetFireCalculation并要求「任一环非SUCCESS即中止」观察失败传播是否被正确拦截。五、小结与下一篇预告本篇立起了官方二次开发的形态底座托管 REST 服务 四种官方客户端端点https://phastwebservices.dnv.com/api/analytics/v1/令牌走环境变量Python 侧用PyPWS包名pypws其六个模块各司其职run()返回ResultCode、失败时靠print_messages()定位、outputState/dischargeRecords是下游取数的接口面。下一篇17 实战一PyPWS 驱动的泄漏—扩散—火灾批量后果分析流水线将把这些零件装成一台机器参数矩阵 → 逐场景全链路 → 失败重试与断点续跑 → 结果落表出图并与 GUI 结果做一致性回归铁律 7。本篇认知问题回显FAQQ1Phast API / Phast Web Services 的官方形态是什么与本地 SDK 的本质区别答官方形态是托管的 Web API 服务Phast Web Services官方门户标题即用 APIs并通过四种官方客户端形态对外提供服务。它与本地 SDK 的本质区别有三点一计算发生在托管侧而非本机客户端只是请求与结果的翻译层二访问需要向 DNV 获取 access token鉴权发生在网络层而非模块导入层三可用形态被官方限定为 Excel / Python / .NET / TypeScript 四种。按未确证项 B 的登记COM / Scripting 独立接口未确证不应假定存在本地 COM 组件调用路径。Q2四种官方客户端分别适合谁计算语义是否同源答Excel 适合工程师手工核对与交付Python 适合自动化流水线.NET 适合企业内部工具集成TypeScript 适合 Web 应用与数字孪生前端。四者是同一套托管计算内核的四个翻译层因此计算语义同源同一组输入在不同客户端间出现差异时应先排查输入装配与单位换算而非怀疑模型实现不同。Q3端点与 access token 是什么关系token 应该放在哪里答端点是官方托管服务的固定访问地址https://phastwebservices.dnv.com/api/analytics/v1/access token 是访问该服务的凭据须向 DNV 获取二者是「地址 通行证」的关系。token 必须通过环境变量或密钥管理注入绝不写入脚本、仓库或日志铁律 5调试时可只打印脱敏后的前若干位以区分「未注入」与「已过期」两类问题。Q4PyPWS 的内部结构怎样组织动手先看哪个模块答公开结构为六个模块pypws.calculations计算对象主入口、pypws.entities输入实体、pypws.enums枚举约束取值、pypws.utilities工具函数如getAnalyticsApiTarget()、pypws.constants常量、pypws.materials物料库检索与自定义物料存取。动手顺序建议为先utilities自检环境与端点再materials选定物料再entities装配输入最后calculations运行——顺序倒置会在批量作业里产生大量无效网络往返。Q5一次计算怎么判成功ResultCode与print_messages()各扮演什么角色答判据是calculation.run()的返回值是否等于ResultCode.SUCCESS这是唯一的成功硬判据。ResultCode负责「成败」这一位信息print_messages()负责在失败时给出诊断消息域是定位失败原因的唯一线索。工程模板应固定为「每次run()后判断结果码非SUCCESS时立即打印诊断并中止链路」避免用日志量替代判定逻辑。Q6为什么全程 SI 单位对接时最容易在哪丢单位答因为 Phast Web Services 以 SI 为统一口径客户端之间的交换尤其 Excel 与 Python 之间只有在同一单位制下才可复现与对账。丢单位最常发生在三处一是把工程单位bar、mm、℃、t/h直接塞进构造参数而未换算二是换算系数散落在多个装配函数里改一处漏一处三是结果只保留报告单位、不留 SI 原值导致无法与官方结果做一致性回归。对策是把换算集中在入参边界与出参边界两处并在结果表中同时留存两套单位。

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号