From f801507961128f0586bf37bf5e0e3ed806b9fd64 Mon Sep 17 00:00:00 2001 From: yumoqing Date: Mon, 13 Jul 2026 16:39:04 +0800 Subject: [PATCH] feat: discount promo code marketing dropdown filter by current org --- models/discount_promo_code.json | 3 +- .../add_discount_promo_code.dspy | 66 +++++ .../delete_discount_promo_code.dspy | 61 +++++ .../get_discount_promo_code.dspy | 127 ++++++++++ wwwroot/discount_promo_code_list/index.ui | 229 ++++++++++++++++++ .../update_discount_promo_code.dspy | 86 +++++++ 6 files changed, 571 insertions(+), 1 deletion(-) create mode 100644 wwwroot/discount_promo_code_list/add_discount_promo_code.dspy create mode 100644 wwwroot/discount_promo_code_list/delete_discount_promo_code.dspy create mode 100644 wwwroot/discount_promo_code_list/get_discount_promo_code.dspy create mode 100644 wwwroot/discount_promo_code_list/index.ui create mode 100644 wwwroot/discount_promo_code_list/update_discount_promo_code.dspy diff --git a/models/discount_promo_code.json b/models/discount_promo_code.json index 6968bdd..2080913 100644 --- a/models/discount_promo_code.json +++ b/models/discount_promo_code.json @@ -86,7 +86,8 @@ "field": "marketing_id", "table": "discount_marketing", "valuefield": "id", - "textfield": "name" + "textfield": "name", + "cond": "resellerid=[[userorgid]]" }, { "field": "code_type", diff --git a/wwwroot/discount_promo_code_list/add_discount_promo_code.dspy b/wwwroot/discount_promo_code_list/add_discount_promo_code.dspy new file mode 100644 index 0000000..a3f9d26 --- /dev/null +++ b/wwwroot/discount_promo_code_list/add_discount_promo_code.dspy @@ -0,0 +1,66 @@ + +ns = params_kw.copy() +for k,v in ns.items(): + if v == 'NaN' or v == 'null': + ns[k] = None +id = params_kw.id +if not id or len(id) > 32: + id = uuid() +ns['id'] = id + + +userid = await get_user() +if not userid: + return { + "widgettype":"Error", + "options":{ + "title":"Authorization Error", + "timeout":3, + "cwidth":16, + "cheight":9, + "message":"Please login" + } + } +ns['sale_id'] = userid + + +userorgid = await get_userorgid() +if not userorgid: + return { + "widgettype":"Error", + "options":{ + "title":"Authorization Error", + "timeout":3, + "cwidth":16, + "cheight":9, + "message":"Please login" + } + } +ns['resellerid'] = userorgid + +db = DBPools() +dbname = get_module_dbname('discount') +async with db.sqlorContext(dbname) as sor: + r = await sor.C('discount_promo_code', ns.copy()) + return { + "widgettype":"Message", + "options":{ + "user_data":ns, + "cwidth":16, + "cheight":9, + "title":"Add Success", + "timeout":3, + "message":"ok" + } + } + +return { + "widgettype":"Error", + "options":{ + "title":"Add Error", + "cwidth":16, + "cheight":9, + "timeout":3, + "message":"failed" + } +} \ No newline at end of file diff --git a/wwwroot/discount_promo_code_list/delete_discount_promo_code.dspy b/wwwroot/discount_promo_code_list/delete_discount_promo_code.dspy new file mode 100644 index 0000000..95074cc --- /dev/null +++ b/wwwroot/discount_promo_code_list/delete_discount_promo_code.dspy @@ -0,0 +1,61 @@ + +ns = { + 'id':params_kw['id'], +} + +userid = await get_user() +if not userid: + return { + "widgettype":"Error", + "options":{ + "title":"Authorization Error", + "timeout":3, + "cwidth":16, + "cheight":9, + "message":"Please login" + } + } +ns['sale_id'] = userid + + +userorgid = await get_userorgid() +if not userorgid: + return { + "widgettype":"Error", + "options":{ + "title":"Authorization Error", + "timeout":3, + "cwidth":16, + "cheight":9, + "message":"Please login" + } + } +ns['resellerid'] = userorgid + +db = DBPools() +dbname = get_module_dbname('discount') +async with db.sqlorContext(dbname) as sor: + r = await sor.D('discount_promo_code', ns) + debug('delete success'); + return { + "widgettype":"Message", + "options":{ + "title":"Delete Success", + "timeout":3, + "cwidth":16, + "cheight":9, + "message":"ok" + } + } + +debug('Delete failed'); +return { + "widgettype":"Error", + "options":{ + "title":"Delete Error", + "timeout":3, + "cwidth":16, + "cheight":9, + "message":"failed" + } +} \ No newline at end of file diff --git a/wwwroot/discount_promo_code_list/get_discount_promo_code.dspy b/wwwroot/discount_promo_code_list/get_discount_promo_code.dspy new file mode 100644 index 0000000..99342e7 --- /dev/null +++ b/wwwroot/discount_promo_code_list/get_discount_promo_code.dspy @@ -0,0 +1,127 @@ + +ns = params_kw.copy() + +userid = await get_user() +if not userid: + return { + "widgettype":"Error", + "options":{ + "title":"Authorization Error", + "timeout":3, + "cwidth":16, + "cheight":9, + "message":"Please login" + } + } +ns['sale_id'] = userid +ns['userid'] = userid + + +userorgid = await get_userorgid() +if not userorgid: + return { + "widgettype":"Error", + "options":{ + "title":"Authorization Error", + "timeout":3, + "cwidth":16, + "cheight":9, + "message":"Please login" + } + } +ns['resellerid'] = userorgid +ns['userorgid'] = userorgid + +debug(f'get_discount_promo_code.dspy:{ns=}') +if not ns.get('page'): + ns['page'] = 1 +if not ns.get('sort'): + + ns['sort'] = 'id' + + +sql = '''select a.*, b.marketing_id_text, c.code_type_text, d.status_text +from (select * from discount_promo_code where 1=1 [[filterstr]]) a left join (select id as marketing_id, + name as marketing_id_text from discount_marketing where resellerid=[[userorgid]]) b on a.marketing_id = b.marketing_id left join (select k as code_type, + v as code_type_text from appcodes_kv where parentid='promo_code_type') c on a.code_type = c.code_type left join (select k as status, + v as status_text from appcodes_kv where parentid='product_status') d on a.status = d.status''' + +filterjson = params_kw.get('data_filter') +if not filterjson: + fields = [ f['name'] for f in [ + { + "name": "id", + "title": "促销码(即id本身)", + "type": "str", + "length": 32, + "nullable": "no" + }, + { + "name": "marketing_id", + "title": "营销方案id(可空=纯邀请码)", + "type": "str", + "length": 32 + }, + { + "name": "resellerid", + "title": "所属商户机构id", + "type": "str", + "length": 32, + "nullable": "no" + }, + { + "name": "sale_id", + "title": "生成销售id", + "type": "str", + "length": 32 + }, + { + "name": "code_type", + "title": "码类型(1=促销码 2=邀请码)", + "type": "char", + "length": 1, + "default": "1", + "nullable": "no" + }, + { + "name": "status", + "title": "状态", + "type": "char", + "length": 1, + "default": "1" + }, + { + "name": "created_at", + "title": "生成时间", + "type": "timestamp", + "nullable": "no" + } +] ] + filterjson = default_filterjson(fields, ns) +filterdic = ns.copy() +filterdic['filterstr'] = '' +filterdic['userorgid'] = '${userorgid}$' +filterdic['userid'] = '${userid}$' +if filterjson: + dbf = DBFilter(filterjson) + conds = dbf.gen(ns) + if conds: + ns.update(dbf.consts) + conds = f' and {conds}' + filterdic['filterstr'] = conds +ac = ArgsConvert('[[', ']]') +vars = ac.findAllVariables(sql) +NameSpace = {v:'${' + v + '}$' for v in vars if v != 'filterstr' } +filterdic.update(NameSpace) +sql = ac.convert(sql, filterdic) + +debug(f'{sql=}') +db = DBPools() +dbname = get_module_dbname('discount') +async with db.sqlorContext(dbname) as sor: + r = await sor.sqlPaging(sql, ns) + return r +return { + "total":0, + "rows":[] +} \ No newline at end of file diff --git a/wwwroot/discount_promo_code_list/index.ui b/wwwroot/discount_promo_code_list/index.ui new file mode 100644 index 0000000..b46689a --- /dev/null +++ b/wwwroot/discount_promo_code_list/index.ui @@ -0,0 +1,229 @@ + +{ + "id":"discount_promo_code_tbl", + "widgettype":"Tabular", + "options":{ + "width":"100%", + "height":"100%", + + + "title":"促销码", + + + + + "toolbar":{ + "tools": [ + { + "name": "generate_qr", + "label": "生成二维码", + "selected_row": true + } + ] +}, + + "css":"card", + + + "editable":{ + + "new_data_url": "{{entire_url('/discount/api/promo_code_create.dspy')}}", + + + "delete_data_url": "{{entire_url('/discount/api/promo_code_delete.dspy')}}", + + + "update_data_url": "{{entire_url('/discount/api/promo_code_update.dspy')}}" + + }, + + + "data_url":"{{entire_url('./get_discount_promo_code.dspy')}}", + + "data_method":"GET", + "data_params":{{json.dumps(params_kw, indent=4, ensure_ascii=False)}}, + "row_options":{ + + + + "browserfields": { + "exclouded": [ + "id" + ], + "marketing_id": { + "title": "营销方案", + "width": 150 + }, + "code_type": { + "title": "类型", + "width": 80 + }, + "status": { + "title": "状态", + "width": 80 + }, + "sale_id": { + "title": "生成销售", + "width": 120, + "uitype": "code", + "valueField": "sale_id", + "textField": "sale_id_text", + "params": { + "dbname": "{{get_module_dbname('discount')}}", + "table": "users", + "tblvalue": "id", + "tbltext": "username", + "valueField": "sale_id", + "textField": "sale_id_text" + }, + "dataurl": "{{entire_url('/appbase/get_code.dspy')}}" + }, + "created_at": { + "title": "生成时间", + "width": 160 + }, + "alters": null +}, + + + "editexclouded":[ + "id", + "resellerid", + "sale_id", + "created_at" +], + + "fields":[ + { + "name": "id", + "title": "促销码(即id本身)", + "type": "str", + "length": 32, + "nullable": "no", + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "促销码(即id本身)" + }, + { + "name": "marketing_id", + "title": "营销方案id(可空=纯邀请码)", + "type": "str", + "length": 32, + "label": "营销方案id(可空=纯邀请码)", + "uitype": "code", + "valueField": "marketing_id", + "textField": "marketing_id_text", + "params": { + "dbname": "{{get_module_dbname('discount')}}", + "table": "discount_marketing", + "tblvalue": "id", + "tbltext": "name", + "valueField": "marketing_id", + "textField": "marketing_id_text", + "cond": "resellerid=[[userorgid]]", + "userorgid": "{{params_kw.userorgid}}" + }, + "dataurl": "{{entire_url('/appbase/get_code.dspy')}}" + }, + { + "name": "resellerid", + "title": "所属商户机构id", + "type": "str", + "length": 32, + "nullable": "no", + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "所属商户机构id" + }, + { + "name": "sale_id", + "title": "生成销售id", + "type": "str", + "length": 32, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "生成销售id" + }, + { + "name": "code_type", + "title": "码类型(1=促销码 2=邀请码)", + "type": "char", + "length": 1, + "default": "1", + "nullable": "no", + "label": "码类型(1=促销码 2=邀请码)", + "uitype": "code", + "valueField": "code_type", + "textField": "code_type_text", + "params": { + "dbname": "{{get_module_dbname('discount')}}", + "table": "appcodes_kv", + "tblvalue": "k", + "tbltext": "v", + "valueField": "code_type", + "textField": "code_type_text", + "cond": "parentid='promo_code_type'" + }, + "dataurl": "{{entire_url('/appbase/get_code.dspy')}}" + }, + { + "name": "status", + "title": "状态", + "type": "char", + "length": 1, + "default": "1", + "label": "状态", + "uitype": "code", + "valueField": "status", + "textField": "status_text", + "params": { + "dbname": "{{get_module_dbname('discount')}}", + "table": "appcodes_kv", + "tblvalue": "k", + "tbltext": "v", + "valueField": "status", + "textField": "status_text", + "cond": "parentid='product_status'" + }, + "dataurl": "{{entire_url('/appbase/get_code.dspy')}}" + }, + { + "name": "created_at", + "title": "生成时间", + "type": "timestamp", + "nullable": "no", + "length": 0, + "uitype": "str", + "datatype": "timestamp", + "label": "生成时间" + } +] + }, + + + + "page_rows":160, + "cache_limit":5 + } + + ,"binds":[ + { + "wid": "self", + "event": "generate_qr", + "actiontype": "urlwidget", + "target": "PopupWindow", + "popup_options": { + "title": "促销码二维码", + "cwidth": 18, + "cheight": 22 + }, + "options": { + "url": "{{entire_url('../api/promo_code_qr.dspy')}}?id=None" + } + } +] + +} \ No newline at end of file diff --git a/wwwroot/discount_promo_code_list/update_discount_promo_code.dspy b/wwwroot/discount_promo_code_list/update_discount_promo_code.dspy new file mode 100644 index 0000000..3c70019 --- /dev/null +++ b/wwwroot/discount_promo_code_list/update_discount_promo_code.dspy @@ -0,0 +1,86 @@ + +ns = params_kw.copy() +for k,v in ns.items(): + if v == 'NaN' or v == 'null': + ns[k] = None + +userid = await get_user() +if not userid: + return { + "widgettype":"Error", + "options":{ + "title":"Authorization Error", + "timeout":3, + "cwidth":16, + "cheight":9, + "message":"Please login" + } + } +ns['sale_id'] = userid + + +userorgid = await get_userorgid() +if not userorgid: + return { + "widgettype":"Error", + "options":{ + "title":"Authorization Error", + "timeout":3, + "cwidth":16, + "cheight":9, + "message":"Please login" + } + } +ns['resellerid'] = userorgid + + + +db = DBPools() +dbname = get_module_dbname('discount') +async with db.sqlorContext(dbname) as sor: + + ns1 = { + + "resellerid": userorgid, + + + "sale_id": userid, + + "id": params_kw.id + } + recs = await sor.R('discount_promo_code', ns1) + if len(recs) < 1: + return { + "widgettype":"Error", + "options":{ + "title":"Update Error", + "cwidth":16, + "cheight":9, + "timeout":3, + "message":"Record no exist or with wrong ownership" + } + } + + r = await sor.U('discount_promo_code', ns) + debug('update success'); + return { + "widgettype":"Message", + "options":{ + "title":"Update Success", + "cwidth":16, + "cheight":9, + "timeout":3, + "message":"ok" + } + } + +return { + "widgettype":"Error", + "options":{ + "title":"Update Error", + "cwidth":16, + "cheight":9, + "timeout":3, + "message":"failed" + } +} \ No newline at end of file