8c2c1bb3c4
feat(storefront): 价格表整体字号×0.7(0.75→0.525,用户2026-09-18:整个价格表缩小)——表头/普通格/价格/原价四处
2026-09-18 17:47:52 +08:00
3dbbb6e480
feat(storefront): 已订阅产线卡删进入产线按钮行(导航由卡片点击承担,用户2026-09-18),流出控件给内容;Jinja三场景验JSON(已订阅无HBox/未订阅留购买/模型留按量)
2026-09-18 17:10:09 +08:00
4f7029f7fe
fix(storefront): 价格表列等宽flex:1 1 0px——filler基宽content依赖致列边界逐行不齐(实测x=501/449交替vs表头513);表头/普通格/价格HBox三处统一
2026-09-18 16:49:14 +08:00
d49790d126
fix(storefront): 让利原价并入价格单元格(HBox并排红价+划线原价)——独立列致行格数≠表头列数错位(2026-09-18实测);Jinja真渲染验row_cells=2对齐+orig划线在格内
2026-09-18 16:45:27 +08:00
aee498de78
refactor(storefront): 价格表去HTML化改bricks声明式控件(用户2026-09-18纠正:不用Html拼table)——core.py只回结构化headers/rows(单元格{t,k}),index.ui用VBox/HBox+Text(tabular-header-row/tabular-row框架双主题类)渲染,价格红/原价划线var(--ink-3)+line-through;Jinja真渲染验JSON合法
2026-09-18 16:37:52 +08:00
04f000e4d1
feat(theme): 主页产品卡片改主题表面(页面底var(--bg-page)/卡片var(--surface-card)/灰阶文字var(--ink-3),语义红与按钮白豁免)——用户要求④暗色卡片
2026-09-18 16:13:38 +08:00
168b84d989
fix(theme): 硬编码暗色字体色改var(--ink-N)主题变量(1文件)——暗色主题下深色文字不可见治理2026-09-17
2026-09-18 14:04:32 +08:00
ac7f0d5267
chore: commit pending local changes (2026-09-17 github sync)
2026-09-17 13:46:06 +08:00
100dbe28cd
feat(storefront): 多价目定价改表格展示——表头=定价要素+价格,行=要素组合对应价
...
病根:qwen-image-3.0-pro 按分辨率×类型四档价,一行文本拼出「按次 ¥0.02 元/张 |
按次 ¥0.02 元/张 | 按次 ¥0.25 元/张 | 按次 ¥0.5 元/张」,客户看不出各价适用条件。
- core.py 新增 _build_price_table:len(prices)>1 时返回 price_table
{headers,rows,html};要素列=计费方式(label有区分度时)+定价维度(filter_labels,
英文维度名中文润饰)+计价因子(factor各行不同时,token三因子);全表同因子(flat)
省略因子列;让利时价格附划线原价;html 全量 escape 防注入
- get_customer_price_display 返回值增 price_table 键;有表格时 original_text 置空
(原价已进表格单元格)
- storefront/index.ui 价格区:有 price_table 渲染 Html 表格,否则原文本路径不变
(单价目无歧义)
- 实测:图像四档/token三因子/视频SR分档/产线包月包年四场景表头行值正确,XSS转义通过
2026-09-09 11:59:14 +08:00
e1963b30c5
fix(storefront): 折扣≥1不显示原价划线——仅让利(折扣<1)时展示原价(展示页+购买页三处同规则)
...
- core.py get_customer_price_display: abs(discount-1)>1e-9 → discount<1.0-1e-9,
加价(如存储1.5)/无折扣(产线1.0)时「原价」低于或等于现价还划线是误导
- purchase_confirm.dspy: 服务端初始算价文本 + 前端JS刷新脚本同款条件修正
- 验证脚本扩至44断言全过(含卡片级无原价/无line-through断言+dspy包装语法检查)
2026-09-08 18:50:43 +08:00
cd58974146
fix(storefront): getWidgetById start point must be bricks.app not app.root - popup DOM is body sibling outside app.root subtree; pay button previously read default values ignoring user input
2026-09-08 18:01:30 +08:00
c74b9cb885
fix(storefront): 多价目产品显示价带因子表头(非缓存输入Token/输出tokens/缓存Token)+模型产品去立即购买按钮改「按量付费」字样
...
- core.py get_customer_price_display 第4步: len(prices)>1 且 label 空/按量/容量时,
段前拼 factor_label(定价YAML fields 的 label),根治裸「¥2.1 元/百万 | ¥8.4 元/百万」
客户看不懂各是什么价;单价目(存储)/产线(包月包年)行为不变
- index.ui: is_model(pipeline_llm_model/llm_model) 卡片无 binds(cursor=default,
不再弹购买框),右下角出「按量付费」文字替代立即购买按钮——purchase_realtime
只支持 account/storage/pipeline,模型消费走推理入口按量落账,购买按钮本身是坏流程
- README 补「商店展示价与卡片行为」节;验证脚本 test_storefront_model_card.py 30断言全过
2026-09-08 17:56:38 +08:00
b0b74a2b9f
feat(storefront): purchase popup shows live price - calc_price.dspy preview endpoint + changed-event refresh on storage_gb/valid_months/charge_mode (same cost basis as purchase_realtime)
2026-09-08 17:53:58 +08:00
1f399d6b00
feat(storefront): 显示价=定价×客户折扣率(三类统一)+产线订阅购买链路+修既有控件bug
...
1) get_customer_price_display 新增(core.py + __init__.py + env 注册)
统一三类产品对外报价口径:显示价 = 资源真实定价 × 客户折扣率
- 产线 pipeline_pricing_map / 存储 storres_pricing_map / 模型 llm_model.ppid
各自解析 ppid → get_pricing_display 取单位价 → × 折扣
- 折扣率解析走 discount 模块 get_min_product_discount(专属优先/'*'兜底/1.0)
>1 加价(存储1.5)、<1 让利(百炼0.9);折扣≠1 时返回 original_text 原价
- 未登录(user_org_id 空)传 '' 只命中 '*' 通用折扣 → 访客可见报价
2) purchase_realtime 加产线分支(product_type=='pipeline')
订阅制:无 usage 表,直接算价→余额预检→product_accounting_generic 实时记账→开订阅权益
charge_mode month/year,entitlement.duration_days 30/365
3) 展示页 index.ui:接 get_customer_price_display;产线卡显示月/年价+原价划线+订阅态文案;
按钮按订阅状态分流(已订阅→进入产线 / 未订阅→立即购买);product_code 兼容
opportunity_general/bidding_general/sdlc_general 与旧 PIPE-* 两套映射
4) 修两个既有 bug(购买页原本就坏):
- InputNumber 控件 bricks 未注册 → widgetBuild 返回 null 静默不渲染,改 UiInt
- 支付脚本 getWidgetById 缺第二参数(查找起点) → from_widget undefined 抛 TypeError
点击支付无反应,补 bricks.app.root;UiType 取值 .value → resultValue()
- UiType 系控件同时传 name(表单/getValue)+id(set_id 覆盖 DOM id 供 getWidgetById)
本地 mock 渲染测试 6 项全过:三类价格/订阅态分流/规划中占位/未登录访客可见价无购买按钮
2026-09-06 16:55:49 +08:00
275806c1cc
fix(product): 账号/存储产品展示缺失——建树KeyError+幽灵列+IN占位符三处修复
...
根因链(2026-09-06):
1. core.get_category_tree 单遍建树隐含「父节点排序在子前」假设:
子类别 sort_order=0 < 顶级 10/20,ORDER BY 后子先处理,
parent['children'].append 时父未初始化 → KeyError → storefront 500
2. storefront get_products.dspy SELECT p.icon——product 表无 icon 列 → 1054
3. 同文件 IN 占位符 f'${key}$' 生成 $cid_0$(缺花括号)sqlor 不识别
配套:init/data.json resource_module 字典补 account_resource/storage_resource
(类别编辑下拉可选),product_type 字典对应项由测试库同步补充。
数据:测试库已建账号资源/存储资源顶级类别并执行导入
(账号3产品:试用7天/月租/年租;存储1产品:工作空间标准存储)。
2026-09-06 14:03:44 +08:00
f2e828c7b6
feat(storefront): 产线产品展示型卡片——进产线入口/规划中占位,不走购买扣款
2026-08-31 08:38:32 +08:00
ff501c13b5
fix(purchase): user_org_id获取崩溃——DictObject的hasattr恒True导致await None()
...
- dspy侧显式取get_userorgid()传入(与purchase_confirm同款)
- core侧hasattr判断改callable检查,兜底_get_current_org_id
2026-08-28 17:09:33 +08:00
c32fa00c62
fix(storefront): purchase_confirm 支付fetch改绝对路径——.dspy非Jinja2渲染,{{entire_url()}}原样进浏览器导致支付按钮无响应
2026-08-28 17:00:16 +08:00
fd794616b3
feat(storefront): 商城改 TabPanel+产品卡片布局; 补齐购买链路权限注册
...
- 展示层重写: 分类=Tab(服务端渲染), 卡片含介绍+真实定价+立即购买按钮,
点击弹购买确认弹窗(purchase_confirm→purchase_realtime 实时记账链路不变)
- 定价文案取资源模块 get_product_display_info(含折扣前的资源真实价)
- load_path 补注册 purchase_confirm/purchase_realtime/my_subscriptions
(此前缺失, 客户点购买会 401)
2026-08-28 16:34:16 +08:00
ymq
167d06cd93
feat(purchase): 实时购买(选A购买即记账)+续费延长+到期门禁+我的权益
...
核心链路:
- purchase_realtime:算价→余额预检→计费写用量→实时复式记账→开权益,失败回滚
- _grant_subscription 续费修复:未到期从 end_date 顺延不丢剩余天数,已到期重算
- check_subscription_valid 到期门禁:挂到 execute_product,到期/未购买阻断使用
- get_my_subscriptions 我的权益列表(到期状态)
- UI:purchase_confirm 确认页(余额+容量/月数输入)、purchase_realtime 支付、
my_subscriptions 权益列表+续费、usermenu.ui 挂菜单
2026-08-27 10:40:54 +08:00
ymq
4ed6d15a59
feat(discount): calculate_product_cost 接产品级折扣
...
折扣精确到 product_id(discount_detail.productid),三类折扣取最优惠(min):
- 客户折扣 get_min_product_discount(pid, resellerid, customerid)
- 分销商折扣 get_min_distributor_discount(pid, resellerid, distributorid)
- 供应商折扣 get_min_supplier_discount(pid, resellerid, supplierid)
resellerid=product.org_id, supplierid=product.providerid,
distributorid 从 discount_customer_bind 按 customerid 查。
2026-08-26 16:04:38 +08:00
91c579cff7
fix: product_query_price改用llm_query_price计价
2026-07-24 16:08:15 +08:00
2c5320bb4a
feat: product_query_price.dspy替代platformbiz版本
2026-07-24 15:49:09 +08:00
8e2c701e23
fix: get_product.dspy清除ns.org_id防止覆盖product_org_auth子查询; JSON修复editable嵌套
2026-07-13 16:39:26 +08:00
9ea13564ef
fix: 导入接受id参数(fallback),错误消息显示category_id
2026-07-13 16:21:24 +08:00
876e4581b7
fix: dspy f-string不能含反斜杠,改用%格式化
2026-07-13 16:15:23 +08:00
f8717ca9a8
debug: import_category_products加参数日志
2026-07-13 16:12:32 +08:00
cfa9b321c4
fix: 导入去除冗余org_id过滤 + 添加providerid回填dspy
...
- import_category_products: 移除org_id条件(树控件已做过滤)
- backfill_providerid: 从llm.providerid回填product.providerid
2026-07-13 15:36:31 +08:00
5f277949ae
feat: product_org_auth model; product_list queries authorized products via product_org_auth
2026-07-10 15:38:29 +08:00
ed32a8556c
fix: CRUD endpoint return format - remove json.dumps, use widgettype format
2026-07-03 14:50:49 +08:00
7b69bb4eb2
chore: remove .swp file, add to gitignore
2026-06-29 16:05:26 +08:00
d33072ab21
debug: product_category_create.dspy 加追踪日志定位 WHERE None 错误
...
添加4处 debug:
- START: 记录完整 params_kw
- fields组装后: 记录 keys + id
- sor.C 前后: 定位崩溃在 INSERT 还是后续 SELECT
- EXCEPTION: 记录完整堆栈
2026-06-29 16:05:18 +08:00
5d77e6e20a
fix: product_category create/update/delete去除json.dumps和import; create补充resource_module
2026-06-29 14:40:09 +08:00
e998e2a4b2
bugfix
2026-06-26 14:00:55 +08:00
339fccf6d2
fix: 产品类别创建使用fields过滤确保列数匹配
2026-06-25 15:35:35 +08:00
84f1453856
fix: 修复产品类别创建时INSERT列数不匹配问题
2026-06-25 15:34:22 +08:00
Hermes Agent
47f7e8e5c1
fix: 树控件创建节点后返回user_data,修复新增子项不显示
2026-06-24 22:13:38 +08:00
Hermes Agent
1438de9d58
refactor: 删除 product_type_config(运营商产品类型配置)功能
...
- 删除 models/product_type_config.json
- 删除 json/product_type_config_list.json (CRUD定义)
- 删除 wwwroot/product_type_config_manage.ui 和 product_type_config_list/ 目录
- 删除 wwwroot/api/product_type_config_{create,update,delete}.dspy
- core.py: 移除 get_operator_config/set_operator_config 方法
- core.py: get_product_detail 不再查询 operator_config
- __init__.py: 移除 wrapper 函数和 env 注册
- product_detail.dspy: 移除 operator_config 查询逻辑
- scripts/load_path.py: 移除所有 product_type_config 权限路径
- menu.ui: 移除"运营商配置"菜单项
- index.ui: 移除"运营商配置"卡片,更新标题描述
- README.md: 移除相关文档
2026-06-24 10:34:48 +08:00
Hermes Agent
6dae1676ef
feat: 新增商家产品商城页面(storefront)
...
- 左侧可收缩产品分类树
- 右侧产品列表(卡片式)和产品详情
- 未登录可浏览,登录后显示购买按钮
- 页面和API注册到load_path.py
2026-06-23 18:19:42 +08:00
Hermes Agent
c78be834d0
refactor: import engine calls resource module's load_product_category_product
...
- core.py: import_categories_and_products() now takes resource_module as first arg,
uses importlib to load {resource_module}.init, calls load_product_category_product(parent_category_id)
- Resource module owns the full import logic (read source + write product_management)
- __init__.py: updated wrapper signature
- import_category_products.dspy: updated call
2026-06-23 14:47:12 +08:00
Hermes Agent
0f321b8185
feat: add resource_module field and import sub-categories/products tool
...
- Add resource_module field to product_category model (stores module name like 'llmage')
- Add resource_module appcode with llmage/supplychain entries to init/data.json
- Add '添加子产品类和产品导入' toolbar tool to tree CRUD (json + generated index.ui)
- Create import_category_products.dspy API endpoint
- Add import_categories_and_products() generic import engine to core.py
- Register import function on ServerEnv
- Update load_path.py with new API endpoint
2026-06-23 13:47:05 +08:00
Hermes Agent
e8f836ba2d
移除临时文件,添加/更新.gitignore
2026-06-22 15:00:30 +08:00
Hermes Agent
f05eea19e5
fix: remove parent_id default '0' from product_category model - Root nodes should have parent_id=NULL, not '0' - Tree query already checks 'parent_id IS NULL' - Revert direct edits to generated dspy files
2026-06-22 14:03:41 +08:00
Hermes Agent
f13651e830
fix: product_category tree root node query + parent_id normalization - get_product_category: accept NULL/empty/'0' as root (parent_id IS NULL OR '' OR '0') - new_product_category: normalize empty/0 parent_id to NULL
2026-06-22 13:59:18 +08:00
Hermes Agent
24605f88e8
fix: datetime->timestamp for audit fields + fix sor.U/sor.I misuse in core.py and API dspy
...
- All 7 models: created_at/updated_at changed from datetime to timestamp type
(DDL template auto-generates DEFAULT CURRENT_TIMESTAMP for timestamp type)
- core.py: fix all sor.U() calls passing 3 args (id must be in data dict)
- core.py: fix sor.I() misuse for INSERT (should be sor.C())
- API dspy updates: fix sor.U() 3-arg bug in category/product/type_config/resource/subscription/supplier
- product_resource_supplier_update.dspy: add missing updated_at field
2026-06-22 11:04:46 +08:00
Hermes Agent
26d374919c
feat: 菜单增加新增功能入口
...
- 产品资源绑定管理
- 资源供应商关联管理
- 客户订购管理
- 产品消费记录查询
2026-06-21 11:44:59 +08:00
Hermes Agent
0e79ddc939
fix: CRUD JSON合规格式(tblname+params) + CRUD create/update/delete dspy + load_path更新
...
- 5个CRUD JSON从自定义格式重写为规范格式(tblname/alias/params)
- 13个新CRUD dspy文件(create/update/delete + noop)
- product_resource_delete含级联删除product_resource_supplier
- product_subscription CRUD含完整校验
- product_usage_log只读(noop dspy)
- load_path.py注册所有新增API和CRUD路径
2026-06-21 11:40:33 +08:00
Hermes Agent
e8860401bc
feat: 产品模块完整功能实现 — 资源绑定/多供应商路由/包月订购/消耗引擎/成本计算
...
新增模型: product_resource, product_resource_supplier, product_subscription, product_usage_log
新增API: 15个.dspy端点(资源绑定/供应商管理/订购/超额/消耗/统计)
新增UI: 4个管理界面(资源绑定/供应商关联/订购管理/消费记录)
核心逻辑: ProductManager新增 bind/unbind/subscribe/product_use/check_quota 等完整业务方法
设计文档: DESIGN.md 完整架构规范
2026-06-20 12:10:32 +08:00
Hermes Agent
bbaa51fcef
fix: 补充CRUD自动生成端点的created_at/updated_at时间戳
2026-06-17 17:57:22 +08:00
Hermes Agent
6bf45a2dfc
fix: remove imports and use pre-loaded timestampstr/getID in create dspy files
...
- product_category_create.dspy: removed import json/time/getID, replaced time.strftime with timestampstr(), removed field filter, pass data directly to sor.C()
- product_create.dspy: removed imports, replaced time.strftime with timestampstr()
- product_type_config_create.dspy: removed imports, replaced time.strftime with timestampstr()
2026-06-17 17:49:47 +08:00