From 047ec1800a437d75b38deb41c52554b96ceac16d Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Wed, 17 Jun 2026 15:18:27 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E5=96=84=E5=88=86=E9=94=80?= =?UTF-8?q?=E5=95=86=E7=AE=A1=E7=90=86CRUD=20=E2=80=94=20sub=5Fdistributor?= =?UTF-8?q?s/distribution=5Fagreements/distribution=5Fagreement=5Fitems?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 增强3个CRUD JSON配置:过滤器、子表关联、下拉选择alters - 修复9个API dspy文件:移除违规import,改用init.py函数直接调用 - 新增2个搜索API:get_search_sub_reseller_id、get_search_agreement_id - 自动生成分销商编号(SD-YYYYMMDD-NNNN)和协议编号(DA-YYYYMMDD-NNNN) - 级联删除:删除分销商时级联删除协议及明细,删除协议时级联删除明细 - 更新load_path.py注册新API路径 --- json/distribution_agreement_items_list.json | 40 +++++++- json/distribution_agreements_list.json | 64 ++++++++++-- json/sub_distributors_list.json | 56 ++++++++++- scripts/load_path.py | 2 + .../distribution_agreement_items_create.dspy | 11 +-- .../distribution_agreement_items_delete.dspy | 11 +-- .../distribution_agreement_items_update.dspy | 11 +-- .../api/distribution_agreements_create.dspy | 11 +-- .../api/distribution_agreements_delete.dspy | 11 +-- .../api/distribution_agreements_update.dspy | 11 +-- wwwroot/api/get_search_agreement_id.dspy | 16 +++ wwwroot/api/get_search_sub_reseller_id.dspy | 16 +++ wwwroot/api/sub_distributors_create.dspy | 30 +----- wwwroot/api/sub_distributors_delete.dspy | 21 +--- wwwroot/api/sub_distributors_update.dspy | 29 +----- .../add_distribution_agreement_items.dspy | 1 + .../get_distribution_agreement_items.dspy | 2 +- .../index.ui | 44 +++++++-- .../add_distribution_agreements.dspy | 17 +++- .../delete_distribution_agreements.dspy | 2 + wwwroot/distribution_agreements_list/index.ui | 26 ++++- .../add_sub_distributors.dspy | 16 ++- .../delete_sub_distributors.dspy | 10 ++ wwwroot/sub_distributors_list/index.ui | 99 ++++++++++++++++++- 24 files changed, 398 insertions(+), 159 deletions(-) create mode 100644 wwwroot/api/get_search_agreement_id.dspy create mode 100644 wwwroot/api/get_search_sub_reseller_id.dspy diff --git a/json/distribution_agreement_items_list.json b/json/distribution_agreement_items_list.json index d5348f0..a8bec63 100644 --- a/json/distribution_agreement_items_list.json +++ b/json/distribution_agreement_items_list.json @@ -1,17 +1,49 @@ { "tblname": "distribution_agreement_items", "alias": "distribution_agreement_items_list", - "title": "分销协议产品折扣", + "title": "分销协议产品折扣管理", "params": { - "sortby": ["prodtypeid", "productid"], + "sortby": [ + "prodtypeid", + "productid" + ], "logined_userorgid": "resellerid", "browserfields": { - "exclouded": ["id", "agreement_id", "resellerid"] + "exclouded": [ + "id", + "agreement_id", + "resellerid" + ], + "alters": { + "agreement_id": { + "uitype": "code", + "dataurl": "{{entire_url('../api/get_search_agreement_id.dspy')}}", + "valueField": "agreement_id", + "textField": "agreement_id_text" + }, + "prodtypeid": { + "uitype": "code", + "dataurl": "{{entire_url('../api/get_search_prodtypeid.dspy')}}", + "valueField": "prodtypeid", + "textField": "prodtypeid_text" + }, + "productid": { + "uitype": "code", + "dataurl": "{{entire_url('../api/get_search_productid.dspy')}}", + "valueField": "productid", + "textField": "productid_text" + } + } }, + "editexclouded": [ + "id", + "resellerid", + "created_at" + ], "editable": { "new_data_url": "{{entire_url('../api/distribution_agreement_items_create.dspy')}}", "update_data_url": "{{entire_url('../api/distribution_agreement_items_update.dspy')}}", "delete_data_url": "{{entire_url('../api/distribution_agreement_items_delete.dspy')}}" } } -} +} \ No newline at end of file diff --git a/json/distribution_agreements_list.json b/json/distribution_agreements_list.json index 78f04c8..790ea0e 100644 --- a/json/distribution_agreements_list.json +++ b/json/distribution_agreements_list.json @@ -3,33 +3,79 @@ "alias": "distribution_agreements_list", "title": "分销协议管理", "params": { - "sortby": ["created_at desc"], + "sortby": [ + "created_at desc" + ], "logined_userorgid": "resellerid", "data_filter": { "AND": [ - {"field": "agreement_name", "op": "LIKE", "var": "agreement_name"}, - {"field": "agreement_code", "op": "LIKE", "var": "agreement_code"}, - {"field": "status", "op": "=", "var": "status"} + { + "field": "agreement_name", + "op": "LIKE", + "var": "agreement_name" + }, + { + "field": "agreement_code", + "op": "LIKE", + "var": "agreement_code" + }, + { + "field": "sub_reseller_id", + "op": "=", + "var": "sub_reseller_id" + }, + { + "field": "status", + "op": "=", + "var": "status" + } ] }, "filter_labels": { "agreement_name": "协议名称", "agreement_code": "协议编号", + "sub_reseller_id": "二级分销商", "status": "状态" }, "browserfields": { - "exclouded": ["id"], + "exclouded": [ + "id", + "resellerid" + ], "alters": { + "sub_reseller_id": { + "uitype": "code", + "dataurl": "{{entire_url('../api/get_search_sub_reseller_id.dspy')}}", + "valueField": "sub_reseller_id", + "textField": "sub_reseller_id_text" + }, "status": { "uitype": "code", "data": [ - {"value": "1", "text": "生效中"}, - {"value": "2", "text": "已到期"}, - {"value": "0", "text": "已终止"} + { + "value": "1", + "text": "生效中" + }, + { + "value": "2", + "text": "已到期" + }, + { + "value": "0", + "text": "已终止" + } ] } } }, + "editexclouded": [ + "id", + "resellerid", + "agreement_code", + "created_by", + "created_at", + "updated_at" + ], "subtables": [ { "field": "agreement_id", @@ -44,4 +90,4 @@ "delete_data_url": "{{entire_url('../api/distribution_agreements_delete.dspy')}}" } } -} +} \ No newline at end of file diff --git a/json/sub_distributors_list.json b/json/sub_distributors_list.json index bac1b75..992d0b7 100644 --- a/json/sub_distributors_list.json +++ b/json/sub_distributors_list.json @@ -1,22 +1,64 @@ { "tblname": "sub_distributors", "alias": "sub_distributors_list", - "title": "二级分销商管理", + "title": "分销商管理", "params": { "sortby": [ "created_at desc" ], "logined_userorgid": "resellerid", + "data_filter": { + "AND": [ + { + "field": "sub_dist_name", + "op": "LIKE", + "var": "sub_dist_name" + }, + { + "field": "sub_dist_code", + "op": "LIKE", + "var": "sub_dist_code" + }, + { + "field": "status", + "op": "=", + "var": "status" + } + ] + }, + "filter_labels": { + "sub_dist_name": "分销商名称", + "sub_dist_code": "分销商编号", + "status": "状态" + }, "browserfields": { "exclouded": [ + "id", + "resellerid", "created_by", "created_at", "updated_at" - ] + ], + "alters": { + "status": { + "uitype": "code", + "data": [ + { + "value": "1", + "text": "正常" + }, + { + "value": "0", + "text": "停用" + } + ] + } + } }, "editexclouded": [ "id", "resellerid", + "sub_dist_code", "created_by", "created_at", "updated_at" @@ -25,6 +67,14 @@ "new_data_url": "{{entire_url('../api/sub_distributors_create.dspy')}}", "update_data_url": "{{entire_url('../api/sub_distributors_update.dspy')}}", "delete_data_url": "{{entire_url('../api/sub_distributors_delete.dspy')}}" - } + }, + "subtables": [ + { + "field": "sub_reseller_id", + "title": "分销协议", + "url": "{{entire_url('../distribution_agreements_list')}}", + "subtable": "distribution_agreements" + } + ] } } \ No newline at end of file diff --git a/scripts/load_path.py b/scripts/load_path.py index 0ed1924..d169d4e 100755 --- a/scripts/load_path.py +++ b/scripts/load_path.py @@ -99,6 +99,8 @@ PATHS_LOGINED = [ "/supplychain/api/get_search_contract_id.dspy", "/supplychain/api/get_search_prodtypeid.dspy", "/supplychain/api/get_search_productid.dspy", + "/supplychain/api/get_search_sub_reseller_id.dspy", + "/supplychain/api/get_search_agreement_id.dspy", # CRUD API — sub_distributors "/supplychain/api/sub_distributors_create.dspy", "/supplychain/api/sub_distributors_update.dspy", diff --git a/wwwroot/api/distribution_agreement_items_create.dspy b/wwwroot/api/distribution_agreement_items_create.dspy index 1ead3de..1077d72 100644 --- a/wwwroot/api/distribution_agreement_items_create.dspy +++ b/wwwroot/api/distribution_agreement_items_create.dspy @@ -1,9 +1,2 @@ -import json -from ahserver.serverenv import ServerEnv -env = ServerEnv() -create_func = getattr(env, 'create_distribution_agreement_items', None) -if create_func is None: - print(json.dumps({"status": "error", "message": "create_distribution_agreement_items function not found"})) -else: - result = await create_func(request, params_kw) - print(result) +result = await create_distribution_agreement_items(request, params_kw) +return json.loads(result) if isinstance(result, str) else result diff --git a/wwwroot/api/distribution_agreement_items_delete.dspy b/wwwroot/api/distribution_agreement_items_delete.dspy index 44d3eb8..c83679a 100644 --- a/wwwroot/api/distribution_agreement_items_delete.dspy +++ b/wwwroot/api/distribution_agreement_items_delete.dspy @@ -1,9 +1,2 @@ -import json -from ahserver.serverenv import ServerEnv -env = ServerEnv() -delete_func = getattr(env, 'delete_distribution_agreement_items', None) -if delete_func is None: - print(json.dumps({"status": "error", "message": "delete_distribution_agreement_items function not found"})) -else: - result = await delete_func(request, params_kw) - print(result) +result = await delete_distribution_agreement_items(request, params_kw) +return json.loads(result) if isinstance(result, str) else result diff --git a/wwwroot/api/distribution_agreement_items_update.dspy b/wwwroot/api/distribution_agreement_items_update.dspy index 5023c0d..bbb7fe2 100644 --- a/wwwroot/api/distribution_agreement_items_update.dspy +++ b/wwwroot/api/distribution_agreement_items_update.dspy @@ -1,9 +1,2 @@ -import json -from ahserver.serverenv import ServerEnv -env = ServerEnv() -update_func = getattr(env, 'update_distribution_agreement_items', None) -if update_func is None: - print(json.dumps({"status": "error", "message": "update_distribution_agreement_items function not found"})) -else: - result = await update_func(request, params_kw) - print(result) +result = await update_distribution_agreement_items(request, params_kw) +return json.loads(result) if isinstance(result, str) else result diff --git a/wwwroot/api/distribution_agreements_create.dspy b/wwwroot/api/distribution_agreements_create.dspy index 2bf09a7..7b4550a 100644 --- a/wwwroot/api/distribution_agreements_create.dspy +++ b/wwwroot/api/distribution_agreements_create.dspy @@ -1,9 +1,2 @@ -import json -from ahserver.serverenv import ServerEnv -env = ServerEnv() -create_func = getattr(env, 'create_distribution_agreements', None) -if create_func is None: - print(json.dumps({"status": "error", "message": "create_distribution_agreements function not found"})) -else: - result = await create_func(request, params_kw) - print(result) +result = await create_distribution_agreements(request, params_kw) +return json.loads(result) if isinstance(result, str) else result diff --git a/wwwroot/api/distribution_agreements_delete.dspy b/wwwroot/api/distribution_agreements_delete.dspy index 0c9ebe4..01fa59e 100644 --- a/wwwroot/api/distribution_agreements_delete.dspy +++ b/wwwroot/api/distribution_agreements_delete.dspy @@ -1,9 +1,2 @@ -import json -from ahserver.serverenv import ServerEnv -env = ServerEnv() -delete_func = getattr(env, 'delete_distribution_agreements', None) -if delete_func is None: - print(json.dumps({"status": "error", "message": "delete_distribution_agreements function not found"})) -else: - result = await delete_func(request, params_kw) - print(result) +result = await delete_distribution_agreements(request, params_kw) +return json.loads(result) if isinstance(result, str) else result diff --git a/wwwroot/api/distribution_agreements_update.dspy b/wwwroot/api/distribution_agreements_update.dspy index 8b9bf6c..1a5e4e9 100644 --- a/wwwroot/api/distribution_agreements_update.dspy +++ b/wwwroot/api/distribution_agreements_update.dspy @@ -1,9 +1,2 @@ -import json -from ahserver.serverenv import ServerEnv -env = ServerEnv() -update_func = getattr(env, 'update_distribution_agreements', None) -if update_func is None: - print(json.dumps({"status": "error", "message": "update_distribution_agreements function not found"})) -else: - result = await update_func(request, params_kw) - print(result) +result = await update_distribution_agreements(request, params_kw) +return json.loads(result) if isinstance(result, str) else result diff --git a/wwwroot/api/get_search_agreement_id.dspy b/wwwroot/api/get_search_agreement_id.dspy new file mode 100644 index 0000000..339d17d --- /dev/null +++ b/wwwroot/api/get_search_agreement_id.dspy @@ -0,0 +1,16 @@ +result = [{'agreement_id': '', 'agreement_id_text': '全部'}] +try: + userorgid = await get_userorgid() + if not userorgid: + return json.dumps(result, ensure_ascii=False) + db = DBPools() + dbname = get_module_dbname('supplychain') + async with db.sqlorContext(dbname) as sor: + rows = await sor.sqlExe( + "select id as agreement_id, agreement_name as agreement_id_text from distribution_agreements where resellerid = ${userorgid}$ and status = '1' order by agreement_name", + {"userorgid": userorgid} + ) + return json.dumps(result + list(rows), ensure_ascii=False) +except Exception as e: + debug(f'get_search_agreement_id error: {e}') +return json.dumps(result, ensure_ascii=False) diff --git a/wwwroot/api/get_search_sub_reseller_id.dspy b/wwwroot/api/get_search_sub_reseller_id.dspy new file mode 100644 index 0000000..9f26563 --- /dev/null +++ b/wwwroot/api/get_search_sub_reseller_id.dspy @@ -0,0 +1,16 @@ +result = [{'sub_reseller_id': '', 'sub_reseller_id_text': '全部'}] +try: + userorgid = await get_userorgid() + if not userorgid: + return json.dumps(result, ensure_ascii=False) + db = DBPools() + dbname = get_module_dbname('supplychain') + async with db.sqlorContext(dbname) as sor: + rows = await sor.sqlExe( + "select id as sub_reseller_id, sub_reseller_name as sub_reseller_id_text from sub_resellers where resellerid = ${userorgid}$ and status = '1' order by sub_reseller_name", + {"userorgid": userorgid} + ) + return json.dumps(result + list(rows), ensure_ascii=False) +except Exception as e: + debug(f'get_search_sub_reseller_id error: {e}') +return json.dumps(result, ensure_ascii=False) diff --git a/wwwroot/api/sub_distributors_create.dspy b/wwwroot/api/sub_distributors_create.dspy index 9d9db23..07e71c3 100644 --- a/wwwroot/api/sub_distributors_create.dspy +++ b/wwwroot/api/sub_distributors_create.dspy @@ -1,28 +1,2 @@ -import json -from appPublic.uniqueID import getID -from datetime import datetime - -async def main(request, params_kw): - """Create a new sub_distributors record.""" - user_id = await get_user() - user_orgid = await get_userorgid() - dbname = get_module_dbname('supplychain') - - data = params_kw.get("data", "{}") - if isinstance(data, str): - data = json.loads(data) - - data["id"] = getID() - data["resellerid"] = user_orgid - data["created_by"] = user_id - data["created_at"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S") - - # Auto-generate sub distributor code - if not data.get("sub_dist_code"): - data["sub_dist_code"] = f"SUB-{datetime.now().strftime('%Y%m%d')}-{getID()[:4].upper()}" - - config = getConfig(".") - DBPools(config.databases) - async with db.sqlorContext(dbname) as sor: - await sor.C("sub_distributors", data) - return json.dumps({"status": "ok", "data": data}) +result = await create_sub_distributors(request, params_kw) +return json.loads(result) if isinstance(result, str) else result diff --git a/wwwroot/api/sub_distributors_delete.dspy b/wwwroot/api/sub_distributors_delete.dspy index 8596548..cea0401 100644 --- a/wwwroot/api/sub_distributors_delete.dspy +++ b/wwwroot/api/sub_distributors_delete.dspy @@ -1,19 +1,2 @@ -import json - -async def main(request, params_kw): - """Delete a sub_distributors record.""" - dbname = get_module_dbname('supplychain') - - data = params_kw.get("data", "{}") - if isinstance(data, str): - data = json.loads(data) - - record_id = data.get("id") - if not record_id: - return json.dumps({"status": "error", "message": "Missing record id"}) - - config = getConfig(".") - DBPools(config.databases) - async with db.sqlorContext(dbname) as sor: - await sor.D("sub_distributors", {"id": record_id}) - return json.dumps({"status": "ok", "message": "Deleted successfully"}) +result = await delete_sub_distributors(request, params_kw) +return json.loads(result) if isinstance(result, str) else result diff --git a/wwwroot/api/sub_distributors_update.dspy b/wwwroot/api/sub_distributors_update.dspy index 0ff8d04..0d5bfab 100644 --- a/wwwroot/api/sub_distributors_update.dspy +++ b/wwwroot/api/sub_distributors_update.dspy @@ -1,27 +1,2 @@ -import json -from datetime import datetime - -async def main(request, params_kw): - """Update a sub_distributors record.""" - user_id = await get_user() - dbname = get_module_dbname('supplychain') - - data = params_kw.get("data", "{}") - if isinstance(data, str): - data = json.loads(data) - - record_id = data.get("id") - if not record_id: - return json.dumps({"status": "error", "message": "Missing record id"}) - - data["updated_at"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S") - - # Remove fields that should not be updated - for key in ["id", "resellerid", "created_by", "created_at"]: - data.pop(key, None) - - config = getConfig(".") - DBPools(config.databases) - async with db.sqlorContext(dbname) as sor: - await sor.U("sub_distributors", data) - return json.dumps({"status": "ok", "data": data}) +result = await update_sub_distributors(request, params_kw) +return json.loads(result) if isinstance(result, str) else result diff --git a/wwwroot/distribution_agreement_items_list/add_distribution_agreement_items.dspy b/wwwroot/distribution_agreement_items_list/add_distribution_agreement_items.dspy index c93185f..e52e00e 100644 --- a/wwwroot/distribution_agreement_items_list/add_distribution_agreement_items.dspy +++ b/wwwroot/distribution_agreement_items_list/add_distribution_agreement_items.dspy @@ -23,6 +23,7 @@ if not userorgid: } } ns['resellerid'] = userorgid +ns['created_at'] = timestampstr() db = DBPools() dbname = get_module_dbname('supplychain') diff --git a/wwwroot/distribution_agreement_items_list/get_distribution_agreement_items.dspy b/wwwroot/distribution_agreement_items_list/get_distribution_agreement_items.dspy index 51c21ac..6fb863c 100644 --- a/wwwroot/distribution_agreement_items_list/get_distribution_agreement_items.dspy +++ b/wwwroot/distribution_agreement_items_list/get_distribution_agreement_items.dspy @@ -23,7 +23,7 @@ if not ns.get('page'): if not ns.get('sort'): - ns['sort'] = ["prodtypeid","productid"] + ns['sort'] = ["prodtypeid", "productid"] diff --git a/wwwroot/distribution_agreement_items_list/index.ui b/wwwroot/distribution_agreement_items_list/index.ui index f50a8dc..f846c84 100644 --- a/wwwroot/distribution_agreement_items_list/index.ui +++ b/wwwroot/distribution_agreement_items_list/index.ui @@ -44,10 +44,36 @@ "id", "agreement_id", "resellerid" - ] + ], + "alters": { + "agreement_id": { + "uitype": "code", + "dataurl": "{{entire_url('../api/get_search_agreement_id.dspy')}}", + "valueField": "agreement_id", + "textField": "agreement_id_text" + }, + "prodtypeid": { + "uitype": "code", + "dataurl": "{{entire_url('../api/get_search_prodtypeid.dspy')}}", + "valueField": "prodtypeid", + "textField": "prodtypeid_text" + }, + "productid": { + "uitype": "code", + "dataurl": "{{entire_url('../api/get_search_productid.dspy')}}", + "valueField": "productid", + "textField": "productid_text" + } + } }, + "editexclouded":[ + "id", + "resellerid", + "created_at" +], + "fields":[ { "name": "id", @@ -78,7 +104,7 @@ "valueField": "agreement_id", "textField": "agreement_id_text" }, - "dataurl": "{{entire_url('/appbase/get_code.dspy')}}" + "dataurl": "{{entire_url('../api/get_search_agreement_id.dspy')}}" }, { "name": "resellerid", @@ -97,9 +123,12 @@ "type": "str", "length": 32, "cwidth": 18, - "uitype": "str", + "uitype": "code", "datatype": "str", - "label": "产品分类ID" + "label": "产品分类ID", + "dataurl": "{{entire_url('../api/get_search_prodtypeid.dspy')}}", + "valueField": "prodtypeid", + "textField": "prodtypeid_text" }, { "name": "productid", @@ -107,9 +136,12 @@ "type": "str", "length": 32, "cwidth": 18, - "uitype": "str", + "uitype": "code", "datatype": "str", - "label": "产品ID" + "label": "产品ID", + "dataurl": "{{entire_url('../api/get_search_productid.dspy')}}", + "valueField": "productid", + "textField": "productid_text" }, { "name": "discount", diff --git a/wwwroot/distribution_agreements_list/add_distribution_agreements.dspy b/wwwroot/distribution_agreements_list/add_distribution_agreements.dspy index 28cf865..39a0c38 100644 --- a/wwwroot/distribution_agreements_list/add_distribution_agreements.dspy +++ b/wwwroot/distribution_agreements_list/add_distribution_agreements.dspy @@ -24,6 +24,21 @@ if not userorgid: } ns['resellerid'] = userorgid +# Auto-generate agreement_code if not provided +if not ns.get('agreement_code'): + from datetime import datetime as _dt + _prefix = f"DA-{_dt.now().strftime('%Y%m%d')}" + async with DBPools().sqlorContext(get_module_dbname('supplychain')) as _sor: + _recs = await _sor.sqlExe( + "SELECT COUNT(*) as cnt FROM distribution_agreements WHERE resellerid = ${rid}$ AND agreement_code LIKE ${p}$", + {"rid": userorgid, "p": _prefix + "%"} + ) + _seq = (_recs[0].cnt if _recs else 0) + 1 + ns['agreement_code'] = f"{_prefix}-{_seq:04d}" +ns['created_by'] = userorgid +ns['created_at'] = timestampstr() +ns['updated_at'] = timestampstr() + db = DBPools() dbname = get_module_dbname('supplychain') async with db.sqlorContext(dbname) as sor: @@ -48,4 +63,4 @@ return { "timeout":3, "message":"failed" } -} \ No newline at end of file +} diff --git a/wwwroot/distribution_agreements_list/delete_distribution_agreements.dspy b/wwwroot/distribution_agreements_list/delete_distribution_agreements.dspy index b76e43c..12ad247 100644 --- a/wwwroot/distribution_agreements_list/delete_distribution_agreements.dspy +++ b/wwwroot/distribution_agreements_list/delete_distribution_agreements.dspy @@ -21,6 +21,8 @@ ns['resellerid'] = userorgid db = DBPools() dbname = get_module_dbname('supplychain') async with db.sqlorContext(dbname) as sor: + # Cascade delete agreement items first + await sor.D('distribution_agreement_items', {'agreement_id': ns['id']}) r = await sor.D('distribution_agreements', ns) debug('delete success'); return { diff --git a/wwwroot/distribution_agreements_list/index.ui b/wwwroot/distribution_agreements_list/index.ui index 0e436c5..f6ee51e 100644 --- a/wwwroot/distribution_agreements_list/index.ui +++ b/wwwroot/distribution_agreements_list/index.ui @@ -52,9 +52,16 @@ "browserfields": { "exclouded": [ - "id" + "id", + "resellerid" ], "alters": { + "sub_reseller_id": { + "uitype": "code", + "dataurl": "{{entire_url('../api/get_search_sub_reseller_id.dspy')}}", + "valueField": "sub_reseller_id", + "textField": "sub_reseller_id_text" + }, "status": { "uitype": "code", "data": [ @@ -76,6 +83,15 @@ }, + "editexclouded":[ + "id", + "resellerid", + "agreement_code", + "created_by", + "created_at", + "updated_at" +], + "fields":[ { "name": "id", @@ -126,7 +142,7 @@ "valueField": "sub_reseller_id", "textField": "sub_reseller_id_text" }, - "dataurl": "{{entire_url('/appbase/get_code.dspy')}}" + "dataurl": "{{entire_url('../api/get_search_sub_reseller_id.dspy')}}" }, { "name": "agreement_code", @@ -271,6 +287,11 @@ "op": "LIKE", "var": "agreement_code" }, + { + "field": "sub_reseller_id", + "op": "=", + "var": "sub_reseller_id" + }, { "field": "status", "op": "=", @@ -283,6 +304,7 @@ "filter_labels":{ "agreement_name": "协议名称", "agreement_code": "协议编号", + "sub_reseller_id": "二级分销商", "status": "状态" }, diff --git a/wwwroot/sub_distributors_list/add_sub_distributors.dspy b/wwwroot/sub_distributors_list/add_sub_distributors.dspy index 229e6ee..1727a15 100644 --- a/wwwroot/sub_distributors_list/add_sub_distributors.dspy +++ b/wwwroot/sub_distributors_list/add_sub_distributors.dspy @@ -24,6 +24,20 @@ if not userorgid: } ns['resellerid'] = userorgid +# Auto-generate sub_dist_code if not provided +if not ns.get('sub_dist_code'): + from datetime import datetime as _dt + _prefix = f"SD-{_dt.now().strftime('%Y%m%d')}" + async with DBPools().sqlorContext(get_module_dbname('supplychain')) as _sor: + _recs = await _sor.sqlExe( + "SELECT COUNT(*) as cnt FROM sub_distributors WHERE resellerid = ${rid}$ AND sub_dist_code LIKE ${p}$", + {"rid": userorgid, "p": _prefix + "%"} + ) + _seq = (_recs[0].cnt if _recs else 0) + 1 + ns['sub_dist_code'] = f"{_prefix}-{_seq:04d}" +ns['created_by'] = userorgid +ns['created_at'] = timestampstr() + db = DBPools() dbname = get_module_dbname('supplychain') async with db.sqlorContext(dbname) as sor: @@ -48,4 +62,4 @@ return { "timeout":3, "message":"failed" } -} \ No newline at end of file +} diff --git a/wwwroot/sub_distributors_list/delete_sub_distributors.dspy b/wwwroot/sub_distributors_list/delete_sub_distributors.dspy index 65beb66..65d08c1 100644 --- a/wwwroot/sub_distributors_list/delete_sub_distributors.dspy +++ b/wwwroot/sub_distributors_list/delete_sub_distributors.dspy @@ -21,6 +21,16 @@ ns['resellerid'] = userorgid db = DBPools() dbname = get_module_dbname('supplychain') async with db.sqlorContext(dbname) as sor: + # Cascade delete distribution_agreement_items first (by agreement_id) + _agreements = await sor.sqlExe( + "SELECT id FROM distribution_agreements WHERE sub_reseller_id = ${sid}$", + {"sid": ns['id']} + ) + for _ag in (_agreements or []): + await sor.D('distribution_agreement_items', {'agreement_id': _ag.id}) + # Cascade delete distribution_agreements + await sor.D('distribution_agreements', {'sub_reseller_id': ns['id']}) + # Delete the sub_distributor r = await sor.D('sub_distributors', ns) debug('delete success'); return { diff --git a/wwwroot/sub_distributors_list/index.ui b/wwwroot/sub_distributors_list/index.ui index d3eaa21..61ab97f 100644 --- a/wwwroot/sub_distributors_list/index.ui +++ b/wwwroot/sub_distributors_list/index.ui @@ -15,6 +15,17 @@ + "toolbar":{ + "tools": [ + { + "selected_row": true, + "name": "distribution_agreements", + "icon": "{{entire_url('/imgs/distribution_agreements.svg')}}", + "label": "分销协议" + } + ] +}, + "css":"card", @@ -41,16 +52,34 @@ "browserfields": { "exclouded": [ + "id", + "resellerid", "created_by", "created_at", "updated_at" - ] + ], + "alters": { + "status": { + "uitype": "code", + "data": [ + { + "value": "1", + "text": "正常" + }, + { + "value": "0", + "text": "停用" + } + ] + } + } }, "editexclouded":[ "id", "resellerid", + "sub_dist_code", "created_by", "created_at", "updated_at" @@ -198,9 +227,19 @@ "nullable": "no", "default": "1", "cwidth": 4, - "uitype": "str", + "uitype": "code", "datatype": "char", - "label": "状态" + "label": "状态", + "data": [ + { + "value": "1", + "text": "正常" + }, + { + "value": "0", + "text": "停用" + } + ] }, { "name": "remark", @@ -245,6 +284,32 @@ + "data_filter":{ + "AND": [ + { + "field": "sub_dist_name", + "op": "LIKE", + "var": "sub_dist_name" + }, + { + "field": "sub_dist_code", + "op": "LIKE", + "var": "sub_dist_code" + }, + { + "field": "status", + "op": "=", + "var": "status" + } + ] +}, + + + "filter_labels":{ + "sub_dist_name": "分销商名称", + "sub_dist_code": "分销商编号", + "status": "状态" +}, @@ -253,7 +318,33 @@ "cache_limit":5 } - ,"binds":[] + ,"binds":[ + { + "wid": "self", + "event": "distribution_agreements", + "actiontype": "urlwidget", + "target": "PopupWindow", + "popup_options": { + "title": "分销协议", + "icon": "{{entire_url('/appbase/get_icon.dspy')}}?id=distribution_agreements", + "resizable": true, + "height": "70%", + "width": "70%" + }, + "params_mapping": { + "mapping": { + "id": "sub_reseller_id", + "referer_widget": "referer_widget" + }, + "need_other": false + }, + "options": { + "method": "POST", + "params": {}, + "url": "{{entire_url('../distribution_agreements_list')}}" + } + } +] }] } \ No newline at end of file