98 Commits

Author SHA1 Message Date
ced49915ed fix(crud): 3个json补alias对齐菜单URL目录名——discount_list/discount_marketing_list/discount_promo_code_list(xls2ui按alias>tblname命名目录,缺alias生成discount/等错名致菜单500);menu.ui同步改新目录名 2026-09-09 15:26:41 +08:00
55b4943170 feat(discount): 折扣率语义扩展——允许>1加价卖给客户+解析改专属优先/*兜底
用户决策(2026-09-06):
1. 折扣率允许大于1:平台可加价卖产品给客户(如存储缺省1.5);
   也可小于1让利(如百炼模型0.9,供应商有折扣传导给客户)
2. 解析规则:确定客户→查客户专属折扣;查不到→'*'通配兜底;再无→1.0
   旧实现bug:专属与通配OR混查取全局min——专属0.95+通配0.8返回0.8,
   专属记录形同虚设

改动:
- init.py sor_get_min_product_discount: 两步查询(专属层min→通配层min)
- init.py add/update_discount_detail: 上限1→9.9999(DB double(5,4)约束)
- discount_setting/save_discount.dspy: 兜底记录识别'*'+NULL两种形态;
  「客户折扣率不得高于通用折扣率」校验保留(加价语义下=单客户价不贵于通用价)
- marketing_discount_setting/save_discount.dspy: >1上限放开,保留<基准约束
- generate_qr.dspy: 同上放开
- index.ui: placeholder 0~1→'>1加价 <1折扣',dec_len 2→4

本地mock测试5场景全过:专属优先/通配兜底/无记录1.0/exact_match不兜底/层内min
2026-09-06 15:43:01 +08:00
ymq
a3d7077acc fix(star_discount): SQL 去掉不存在的 d.discount 列
discount 表无 discount 字段(值在 discount_detail 表)。原 select d.id, d.discount
导致 reseller 级通用折扣(customerid=NULL)查询永远报 Unknown column 错误,
被上层 try/except 兜住后 fallback 到 1.0,通用折扣形同虚设。
2026-08-26 15:52:03 +08:00
8a22ab961e simplify: DSPY直接读id,params_mapping透传,不重命名 2026-08-05 19:14:22 +08:00
0144129ec1 fix: 参数名改用mkt_id避免与行数据marketing_id字段冲突,照抄产品明细params_mapping模式 2026-08-05 18:14:31 +08:00
1e771df6e5 feat: 营销方案CRUD添加「生成促销码」工具按钮 — 选中方案后一键生成该用户的促销码 2026-08-05 16:26:42 +08:00
49cae8a64d chore: 移除xls2ui生成文件,wwwroot子目录加入gitignore 2026-07-14 17:24:47 +08:00
6c0f5a6572 fix: customerid改存orgid; init_free按机构去重; 查询回JOIN organization 2026-07-14 11:18:13 +08:00
1e0081862d fix: use empty string instead of None for NOT NULL sale_id/promo_code_id 2026-07-14 10:45:07 +08:00
f6c29c8c38 fix: use get_module_dbname for discount db in init_free_customers 2026-07-14 10:44:23 +08:00
e4b746be5c fix: init_free_customers allow owner org, use users.orgid as resellerid 2026-07-14 10:41:52 +08:00
9d3c4e0adf feat: init_free_customers.dspy + button in free_customer_assign 2026-07-14 10:38:02 +08:00
1e99ad2cc8 fix: hide resellerid in customer_bind list, add menu entries for free_customer_assign + customer_reassign 2026-07-13 18:36:51 +08:00
029fd91d79 feat: customer assignment - free_customer_assign + customer_reassign pages, register hook bind_type=3, sales list filter 2026-07-13 17:56:05 +08:00
f801507961 feat: discount promo code marketing dropdown filter by current org 2026-07-13 16:39:04 +08:00
34a2fecc99 fix: from discount.init import bind_customer, 绕过dspy bare function 查找失败 2026-07-06 14:55:32 +08:00
9a8d7f10aa fix: dspy缺少return result导致返回None 2026-07-06 14:49:10 +08:00
2bbe82fd23 fix: 用dspy原生bare function(get_user/entire_url/bind_customer),去掉env间接调用 2026-07-06 14:41:20 +08:00
79494622b9 fix: env = request._run_ns 替代 ServerEnv(),修复dspy中get_user返回None 2026-07-06 14:39:44 +08:00
5762e1c361 fix: 登录URL /rbac/user/login -> /rbac/user/login.ui 2026-07-06 14:34:22 +08:00
9bb5c9e506 促销码扫码流程: dspy端点改为UI公开入口,登录后绑定并跳转主页
- 新建 promote/index.ui: 公开入口,未登录显示登录按钮,已登录自动跳dspy
- QR URL 改为 promote/index.ui (原 promote.dspy)
- load_path.py 注册 promote/index.ui 为 any 角色
- index.dspy 绑定成功后显示返回首页按钮跳转主页
- 修复 generate_promo_code sale_id: get_user() -> get_userid()
2026-07-06 13:34:25 +08:00
e06339f95d feat: 客户归属管理——列出机构客户+分配销售 2026-07-05 14:44:40 +08:00
ab9dc4f730 fix: promote.dspy最终版——去binds避免服务端script解析,用request._run_ns.params_kw 2026-07-05 11:09:33 +08:00
3797ae1686 fix: promote.dspy加回binds用request._run_ns 2026-07-05 11:08:41 +08:00
f50284df3e fix: promote.dspy用request._run_ns.params_kw替代params_kw 2026-07-05 11:08:02 +08:00
c5778ba79b debug: 去params_kw直接返回硬编码表单 2026-07-05 11:07:26 +08:00
fc73c7d2d6 debug: promote.dspy去binds排查500 2026-07-05 11:06:23 +08:00
a5c01d6bed fix: restore promote.dspy完整表单验证JSON解析 2026-07-05 11:05:37 +08:00
e83a9ae414 debug: 回退promote.dspy到最小化版本测试 2026-07-05 11:03:35 +08:00
7daff0fcd6 fix: QR URL改为promote.dspy; 恢复完整表单 2026-07-05 11:02:41 +08:00
2d6fa91ec5 debug: promote.dspy最小化排除语法错误 2026-07-05 11:00:37 +08:00
26efde3051 fix: promote页移到RBAC any角色(无需登录),客户扫码可用 2026-07-05 10:58:29 +08:00
4b7e501ee0 fix: promote.dspy替代promote.ui绕过模板引擎500 2026-07-05 10:42:36 +08:00
bea89dadd5 fix: promote.ui加Jinja2注释标记强制走模板引擎路径 2026-07-05 10:40:45 +08:00
5c2079a2f1 fix: promote.ui去掉Jinja2 entire_url避免独立页面上下文缺失 2026-07-05 10:39:09 +08:00
0ceb2b84c1 fix: QR生成移到async Python函数,修复DSPY中async/await不可用问题 2026-07-05 10:36:12 +08:00
85f9979051 fix: in_plan整数比较==1而非=='1' 2026-07-04 20:35:23 +08:00
8173fb603b fix: title用json.dumps整个字符串避免空值破坏JSON 2026-07-04 20:34:30 +08:00
c3cad2140f fix: 用json.dumps包裹所有动态值确保JSON安全,in_plan用字符串比较'1' 2026-07-04 20:33:56 +08:00
ad56bd4b37 fix: index.ui literal \t → actual TAB for valid JSON output 2026-07-04 20:25:17 +08:00
cd69111655 fix: add p.id to SELECT for sqlPaging default ORDER BY id 2026-07-04 19:59:53 +08:00
da88b99ca1 fix: hardcode base_discountid to avoid sqlExe KeyError in DSPY 2026-07-04 19:58:55 +08:00
9645d397b6 fix: remove ns['sort'] to avoid sqlPaging outer ORDER BY conflict 2026-07-04 19:56:56 +08:00
9c7a39e519 fix: remove inner ORDER BY to prevent sqlPaging conflict 2026-07-04 19:55:48 +08:00
7a267558a3 fix: DSPY sort alias pc.name→pc_name for sqlPaging compatibility 2026-07-04 19:53:43 +08:00
bc8af7a4cf fix: 产品折扣设置显示基准折扣(1.0)并标记方案内产品
- get_discount_setting_products: LEFT JOIN基准折扣方案_HeaX, COALESCE优先方案折扣, 新增in_plan字段
- get_products_with_discount.dspy: 同步加基准折扣COALESCE
- index.ui: 折扣默认1.0, 新增'✓方案内'标记列
- save_discount: old_discount默认1.0
2026-07-04 19:49:02 +08:00
51a1616b9f fix: restore IS NULL OR * to cover both conventions; keep direct dd.discount without GROUP BY 2026-07-03 18:06:56 +08:00
c39e54f379 fix: dspy same fix — remove IS NULL, remove GROUP BY, use dd.discount directly 2026-07-03 18:05:41 +08:00
33cd1d287d feat: 营销方案产品折扣设置(独立于普通折扣方案)
index.ui: 显示所有产品 + 基准折扣(全部用户) + 方案折扣, 标志'已加入/未加入'
get_products.dspy: 左联全部用户基准折扣 + 营销方案专属折扣
save_discount.dspy: 验证 0<新<基准, upsert 到 discount_detail
init.py: get_marketing_discount_products + get_marketing_info
marketing_list.json: toolbar 指向新页面
2026-07-03 16:05:21 +08:00
ae6c547aff fix: CRUD endpoint return format - remove json.dumps, use widgettype format 2026-07-03 14:50:31 +08:00