feat: 独立产品折扣设置页面(全量产品列表+行内upsert)
This commit is contained in:
parent
b2691fe02a
commit
29578196a1
@ -32,8 +32,8 @@
|
||||
"subtables": [
|
||||
{
|
||||
"field": "discountid",
|
||||
"title": "折扣产品明细",
|
||||
"subtable": "discount_detail_list"
|
||||
"title": "设置产品折扣",
|
||||
"subtable": "discount_setting"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
44
wwwroot/api/get_product_discount_list.dspy
Normal file
44
wwwroot/api/get_product_discount_list.dspy
Normal file
@ -0,0 +1,44 @@
|
||||
# 获取用户机构的所有产品及其折扣信息
|
||||
# 用于折扣明细设置页面
|
||||
|
||||
ns = params_kw.copy()
|
||||
discountid = ns.get('discountid')
|
||||
|
||||
if not discountid:
|
||||
return {"total": 0, "rows": []}
|
||||
|
||||
user_orgid = await get_userorgid()
|
||||
if not user_orgid:
|
||||
return {"total": 0, "rows": []}
|
||||
|
||||
if not ns.get('page'):
|
||||
ns['page'] = 1
|
||||
if not ns.get('sort'):
|
||||
ns['sort'] = 'category_id, product_name'
|
||||
|
||||
# 查询用户机构的所有产品,LEFT JOIN折扣明细
|
||||
sql = '''
|
||||
SELECT
|
||||
p.id as productid,
|
||||
p.product_name,
|
||||
p.product_code,
|
||||
p.category_id,
|
||||
pc.name as category_name,
|
||||
COALESCE(dd.id, '') as detail_id,
|
||||
COALESCE(dd.discount, 0) as discount
|
||||
FROM product p
|
||||
LEFT JOIN product_category pc ON p.category_id = pc.id
|
||||
LEFT JOIN discount_detail dd ON dd.productid = p.id AND dd.discountid = ${discountid}$
|
||||
WHERE p.org_id = ${org_id}$ AND p.status = '1'
|
||||
ORDER BY p.category_id, p.product_name
|
||||
'''
|
||||
|
||||
ns['org_id'] = user_orgid
|
||||
ns['discountid'] = discountid
|
||||
|
||||
db = DBPools()
|
||||
dbname = get_module_dbname('discount')
|
||||
async with db.sqlorContext(dbname) as sor:
|
||||
r = await sor.sqlPaging(sql, ns)
|
||||
debug(f'get_product_discount_list: {len(r.get("rows", []))} products')
|
||||
return r
|
||||
43
wwwroot/discount_setting/get_products_with_discount.dspy
Normal file
43
wwwroot/discount_setting/get_products_with_discount.dspy
Normal file
@ -0,0 +1,43 @@
|
||||
# 查询用户所在机构的所有产品及其折扣信息
|
||||
# 参数: discountid (必需)
|
||||
|
||||
discountid = params_kw.get('discountid')
|
||||
if not discountid:
|
||||
return {"total": 0, "rows": []}
|
||||
|
||||
user_orgid = await get_userorgid()
|
||||
if not user_orgid:
|
||||
return {"total": 0, "rows": []}
|
||||
|
||||
ns = params_kw.copy()
|
||||
if not ns.get('page'):
|
||||
ns['page'] = 1
|
||||
if not ns.get('sort'):
|
||||
ns['sort'] = 'category_name, product_name'
|
||||
|
||||
sql = '''
|
||||
SELECT
|
||||
p.id as productid,
|
||||
p.product_code,
|
||||
p.product_name,
|
||||
p.category_id,
|
||||
pc.name as category_name,
|
||||
dd.id as detail_id,
|
||||
dd.discount,
|
||||
dd.discountid
|
||||
FROM product p
|
||||
LEFT JOIN product_category pc ON p.category_id = pc.id
|
||||
LEFT JOIN discount_detail dd ON dd.productid = p.id
|
||||
AND dd.discountid = ${discountid}$
|
||||
WHERE p.org_id = ${org_id}$ AND p.status = '1'
|
||||
ORDER BY pc.name, p.product_name
|
||||
'''
|
||||
|
||||
ns['org_id'] = user_orgid
|
||||
|
||||
db = DBPools()
|
||||
dbname = get_module_dbname('discount')
|
||||
async with db.sqlorContext(dbname) as sor:
|
||||
r = await sor.sqlPaging(sql, ns)
|
||||
debug(f'get_products_with_discount: {len(r.get("rows", []))} products for org {user_orgid}')
|
||||
return r
|
||||
71
wwwroot/discount_setting/index.ui
Normal file
71
wwwroot/discount_setting/index.ui
Normal file
@ -0,0 +1,71 @@
|
||||
{
|
||||
"widgettype": "VBox",
|
||||
"options": {"height": "100%", "width": "100%"},
|
||||
"subwidgets": [
|
||||
{
|
||||
"id": "product_discount_tbl",
|
||||
"widgettype": "Tabular",
|
||||
"options": {
|
||||
"width": "100%",
|
||||
"height": "100%",
|
||||
"title": "产品折扣设置",
|
||||
"description": "选中产品后点击工具栏按钮设置折扣",
|
||||
"css": "card",
|
||||
"toolbar": {
|
||||
"tools": [
|
||||
{
|
||||
"name": "set_discount",
|
||||
"label": "设置折扣",
|
||||
"selected_row": true,
|
||||
"icon": "{{entire_url('/bricks/imgs/edit.svg')}}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"data_url": "{{entire_url('./get_products_with_discount.dspy')}}",
|
||||
"data_method": "GET",
|
||||
"data_params": {},
|
||||
"row_options": {
|
||||
"idField": "productid",
|
||||
"checkField": "checked",
|
||||
"fields": [
|
||||
{
|
||||
"name": "category_name",
|
||||
"title": "产品分类",
|
||||
"type": "str",
|
||||
"cwidth": 2
|
||||
},
|
||||
{
|
||||
"name": "product_name",
|
||||
"title": "产品名称",
|
||||
"type": "str",
|
||||
"cwidth": 4
|
||||
},
|
||||
{
|
||||
"name": "product_code",
|
||||
"title": "产品编码",
|
||||
"type": "str",
|
||||
"cwidth": 3
|
||||
},
|
||||
{
|
||||
"name": "discount",
|
||||
"title": "当前折扣",
|
||||
"type": "float",
|
||||
"cwidth": 2
|
||||
}
|
||||
]
|
||||
},
|
||||
"page_rows": 100,
|
||||
"cache_limit": 5
|
||||
},
|
||||
"binds": [
|
||||
{
|
||||
"wid": "set_discount",
|
||||
"event": "click",
|
||||
"actiontype": "script",
|
||||
"target": "self",
|
||||
"script": "var dv = bricks.getWidgetById('product_discount_tbl', bricks.app.root); if (!dv || !dv.select_row || !dv.select_row.user_data) { alert('请先选中一个产品'); return; } var row = dv.select_row.user_data; var discountid = new URLSearchParams(window.location.search).get('discountid') || ''; var mf = new bricks.ModalForm({title: '设置折扣 - ' + row.product_name, width: '400px', auto_open: true, fields: [{name: 'discountid', uitype: 'hide', value: discountid}, {name: 'productid', uitype: 'hide', value: row.productid}, {name: 'category_id', uitype: 'hide', value: row.category_id}, {name: 'detail_id', uitype: 'hide', value: row.detail_id || ''}, {name: 'product_name', label: '产品', uitype: 'text', value: row.product_name}, {name: 'category_name', label: '分类', uitype: 'text', value: row.category_name}, {name: 'discount', label: '折扣(0-1)', uitype: 'float', value: row.discount || '', tip: '0到1之间,如0.8表示8折,留空或0表示清除折扣'}], submit_url: '{{entire_url(\"./save_discount.dspy\")}}'}); mf.bind('submited', async function(params) { await bricks.show_resp_message_or_error(params); await dv.render({}); });"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
54
wwwroot/discount_setting/save_discount.dspy
Normal file
54
wwwroot/discount_setting/save_discount.dspy
Normal file
@ -0,0 +1,54 @@
|
||||
# Upsert折扣明细:有detail_id则更新,无则新增
|
||||
# 参数: discountid, productid, category_id, discount, detail_id(可选)
|
||||
|
||||
result = {'widgettype': 'Message', 'options': {'title': 'Error', 'message': 'Invalid', 'type': 'error'}}
|
||||
|
||||
try:
|
||||
discountid = params_kw.get('discountid')
|
||||
productid = params_kw.get('productid')
|
||||
category_id = params_kw.get('category_id')
|
||||
discount_val = params_kw.get('discount')
|
||||
detail_id = params_kw.get('detail_id')
|
||||
|
||||
if not discountid or not productid:
|
||||
raise Exception('缺少必要参数: discountid, productid')
|
||||
|
||||
# discount为0或空时,如果已有记录则删除
|
||||
if not discount_val or float(discount_val) == 0:
|
||||
if detail_id:
|
||||
dbname = get_module_dbname('discount')
|
||||
async with DBPools().sqlorContext(dbname) as sor:
|
||||
await sor.D('discount_detail', {'id': detail_id})
|
||||
result = {'widgettype': 'Message', 'options': {'title': 'Success', 'message': '折扣已清除', 'type': 'success'}}
|
||||
else:
|
||||
result = {'widgettype': 'Message', 'options': {'title': 'Success', 'message': 'ok', 'type': 'success'}}
|
||||
return result
|
||||
|
||||
dbname = get_module_dbname('discount')
|
||||
user_orgid = await get_userorgid()
|
||||
|
||||
async with DBPools().sqlorContext(dbname) as sor:
|
||||
if detail_id:
|
||||
# 更新
|
||||
await sor.U('discount_detail', {
|
||||
'id': detail_id,
|
||||
'discount': float(discount_val)
|
||||
})
|
||||
else:
|
||||
# 新增
|
||||
await sor.C('discount_detail', {
|
||||
'id': uuid(),
|
||||
'discountid': discountid,
|
||||
'resellerid': user_orgid,
|
||||
'prodtypeid': category_id,
|
||||
'productid': productid,
|
||||
'discount': float(discount_val)
|
||||
})
|
||||
|
||||
result = {'widgettype': 'Message', 'options': {'title': 'Success', 'message': '折扣保存成功', 'type': 'success'}}
|
||||
|
||||
except Exception as e:
|
||||
debug(f'save_discount error: {e}')
|
||||
result['options'] = {'title': 'Error', 'message': f'保存失败: {str(e)}', 'type': 'error'}
|
||||
|
||||
return result
|
||||
Loading…
x
Reference in New Issue
Block a user