From 1438de9d582963dcd4b759482a7dc68d464989a2 Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Wed, 24 Jun 2026 10:34:48 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E5=88=A0=E9=99=A4=20product=5Ftype?= =?UTF-8?q?=5Fconfig=EF=BC=88=E8=BF=90=E8=90=A5=E5=95=86=E4=BA=A7=E5=93=81?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E9=85=8D=E7=BD=AE=EF=BC=89=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 删除 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: 移除相关文档 --- README.md | 8 +- json/product_type_config_list.json | 41 ---- models/product_type_config.json | 122 ---------- product_management/__init__.py | 14 +- product_management/core.py | 132 +--------- scripts/load_path.py | 10 - wwwroot/api/product_detail.dspy | 29 +-- wwwroot/api/product_type_config_create.dspy | 26 -- wwwroot/api/product_type_config_delete.dspy | 31 --- wwwroot/api/product_type_config_update.dspy | 32 --- wwwroot/index.ui | 38 +-- wwwroot/menu.ui | 3 +- .../add_product_type_config.dspy | 67 ------ .../delete_product_type_config.dspy | 61 ----- .../get_product_type_config.dspy | 148 ------------ wwwroot/product_type_config_list/index.ui | 227 ------------------ .../update_product_type_config.dspy | 87 ------- wwwroot/product_type_config_manage.ui | 16 -- 18 files changed, 9 insertions(+), 1083 deletions(-) delete mode 100644 json/product_type_config_list.json delete mode 100644 models/product_type_config.json delete mode 100644 wwwroot/api/product_type_config_create.dspy delete mode 100644 wwwroot/api/product_type_config_delete.dspy delete mode 100644 wwwroot/api/product_type_config_update.dspy delete mode 100644 wwwroot/product_type_config_list/add_product_type_config.dspy delete mode 100644 wwwroot/product_type_config_list/delete_product_type_config.dspy delete mode 100644 wwwroot/product_type_config_list/get_product_type_config.dspy delete mode 100644 wwwroot/product_type_config_list/index.ui delete mode 100644 wwwroot/product_type_config_list/update_product_type_config.dspy delete mode 100644 wwwroot/product_type_config_manage.ui diff --git a/README.md b/README.md index 3ec6cef..1b2c0ac 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,6 @@ product_management 是产品生命周期的中枢,负责: |------|------| | `product_category` | 产品类别树(parent_id 层级关系,resource_module 标记来源模块) | | `product` | 产品注册表(resource_ref_id 关联资源模块内部ID) | -| `product_type_config` | 产品类型配置(运营者级别的 JSON 配置) | | `product_resource` | 产品-资源绑定(一个产品可绑定多个资源,含配额和溢出产品) | | `product_resource_supplier` | 资源绑定的供应商路由(优先级+权重) | | `product_subscription` | 产品订阅(月度/按量,含配额跟踪和溢出计费) | @@ -118,12 +117,10 @@ def load_product_management(): # 基础 CRUD env.get_product_brief = get_product_brief env.get_product_detail = get_product_detail - env.get_category_tree = get_category_tree - env.get_products_by_category = get_products_by_category env.purchase_product = purchase_product env.use_product = use_product - env.get_operator_config = get_operator_config - env.set_operator_config = set_operator_config + env.get_category_tree = get_category_tree + env.get_products_by_category = get_products_by_category env.import_categories_and_products = import_categories_and_products # 资源模块接口调度 env.get_product_display_info = get_product_display_info @@ -255,7 +252,6 @@ product_management/ │ ├── product_resource.json │ ├── product_resource_supplier.json │ ├── product_subscription.json -│ ├── product_type_config.json │ └── product_usage_log.json ├── product_management/ │ ├── __init__.py # ServerEnv 注册 + 入口函数 diff --git a/json/product_type_config_list.json b/json/product_type_config_list.json deleted file mode 100644 index f766e06..0000000 --- a/json/product_type_config_list.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "tblname": "product_type_config", - "alias": "product_type_config_list", - "title": "运营商产品类型配置", - "params": { - "sortby": ["created_at desc"], - "logined_userorgid": "org_id", - "logined_userid": "operator_id", - "data_filter": { - "AND": [ - {"field": "config_name", "op": "LIKE", "var": "config_name"} - ] - }, - "filter_labels": { - "config_name": "配置名称" - }, - "browserfields": { - "exclouded": [], - "alters": { - "category_id": { - "uitype": "code", - "dataurl": "{{entire_url('../api/category_options.dspy')}}", - "datamethod": "GET" - }, - "enabled_flg": { - "uitype": "code", - "data": [ - {"value": "1", "text": "启用"}, - {"value": "0", "text": "禁用"} - ] - } - } - }, - "editexclouded": ["operator_id", "created_by", "created_at", "updated_at"], - "editable": { - "new_data_url": "{{entire_url('../api/product_type_config_create.dspy')}}", - "update_data_url": "{{entire_url('../api/product_type_config_update.dspy')}}", - "delete_data_url": "{{entire_url('../api/product_type_config_delete.dspy')}}" - } - } -} diff --git a/models/product_type_config.json b/models/product_type_config.json deleted file mode 100644 index 85e7325..0000000 --- a/models/product_type_config.json +++ /dev/null @@ -1,122 +0,0 @@ -{ - "summary": [ - { - "name": "product_type_config", - "title": "运营商产品类型配置", - "primary": [ - "id" - ], - "catelog": "relation" - } - ], - "fields": [ - { - "name": "id", - "title": "主键ID", - "type": "str", - "length": 32, - "nullable": "no" - }, - { - "name": "operator_id", - "title": "运营商用户ID", - "type": "str", - "length": 32, - "nullable": "no" - }, - { - "name": "org_id", - "title": "所属机构ID", - "type": "str", - "length": 32, - "nullable": "no" - }, - { - "name": "category_id", - "title": "产品类别ID", - "type": "str", - "length": 32, - "nullable": "no" - }, - { - "name": "config_name", - "title": "配置名称", - "type": "str", - "length": 255, - "nullable": "no" - }, - { - "name": "config_json", - "title": "配置内容", - "type": "text" - }, - { - "name": "enabled_flg", - "title": "是否启用", - "type": "char", - "length": 1, - "default": "1" - }, - { - "name": "created_by", - "title": "创建人", - "type": "str", - "length": 32 - }, - { - "name": "created_at", - "title": "创建时间", - "type": "timestamp", - "nullable": "no" - }, - { - "name": "updated_at", - "title": "更新时间", - "type": "timestamp", - "nullable": "no" - } - ], - "indexes": [ - { - "name": "idx_ptc_org_opr", - "idxtype": "index", - "idxfields": [ - "org_id", - "operator_id" - ] - }, - { - "name": "idx_ptc_org_cat", - "idxtype": "unique", - "idxfields": [ - "org_id", - "operator_id", - "category_id", - "config_name" - ] - }, - { - "name": "idx_ptc_enabled", - "idxtype": "index", - "idxfields": [ - "enabled_flg" - ] - } - ], - "codes": [ - { - "field": "category_id", - "table": "product_category", - "valuefield": "id", - "textfield": "name", - "cond": "has_product='1' AND status='1'" - }, - { - "field": "enabled_flg", - "table": "appcodes_kv", - "valuefield": "k", - "textfield": "v", - "cond": "parentid='enabled_flg'" - } - ] -} diff --git a/product_management/__init__.py b/product_management/__init__.py index 159a3ff..80fda7c 100644 --- a/product_management/__init__.py +++ b/product_management/__init__.py @@ -55,17 +55,6 @@ async def get_products_by_category(category_id, status='1'): return await manager.get_products_by_category(category_id, status) -async def get_operator_config(category_id, user_id=None): - """Get operator configuration for a category.""" - manager = get_manager() - return await manager.get_operator_config(category_id, user_id) - - -async def set_operator_config(category_id, config_name, config_json, user_id=None, org_id=None): - """Create or update operator configuration for a category.""" - manager = get_manager() - return await manager.set_operator_config(category_id, config_name, config_json, user_id, org_id) - async def import_categories_and_products(resource_module, org_id, parent_category_id, user_id): """Import sub-categories and products from a resource module.""" @@ -120,8 +109,7 @@ def load_product_management(): env.use_product = use_product env.get_category_tree = get_category_tree env.get_products_by_category = get_products_by_category - env.get_operator_config = get_operator_config - env.set_operator_config = set_operator_config + env.import_categories_and_products = import_categories_and_products # Resource module interface dispatchers env.get_product_display_info = get_product_display_info diff --git a/product_management/core.py b/product_management/core.py index 98f0174..acae3e3 100644 --- a/product_management/core.py +++ b/product_management/core.py @@ -177,7 +177,7 @@ class ProductManager: async def get_product_detail(self, product_id=None, product_code=None, org_id=None, user_id=None): """Get product detail for current org (reseller). - Returns product_info + category_info + operator_config + extra_parsed. + Returns product_info + category_info + extra_parsed. """ if not org_id: org_id = self._get_current_org_id() @@ -225,29 +225,6 @@ class ProductManager: extra_parsed = {'_raw': extra_str} product_info['extra_parsed'] = extra_parsed - # Get operator config for this category - config_sql = """SELECT * FROM product_type_config - WHERE category_id = ${category_id}$ - AND org_id = ${org_id}$ - AND enabled_flg = '1' - AND (operator_id = ${user_id}$ OR operator_id = '0') - ORDER BY created_at DESC LIMIT 1""" - config_rows = await sor.sqlExe(config_sql, { - 'category_id': product_info['category_id'], - 'org_id': org_id, - 'user_id': user_id - }) - - operator_config = {} - if config_rows: - operator_config = dict(config_rows[0]) - config_json = operator_config.get('config_json', '') - if config_json: - try: - operator_config['config_parsed'] = json.loads(config_json) - except: - operator_config['config_parsed'] = {} - return { 'success': True, 'data': { @@ -255,8 +232,7 @@ class ProductManager: 'category_info': { 'name': product_info.get('category_name'), 'description': product_info.get('category_description') - }, - 'operator_config': operator_config + } } } @@ -387,110 +363,6 @@ class ProductManager: 'message': 'Product use successful' } - async def get_operator_config(self, category_id, org_id=None, user_id=None): - """Get operator configuration for a category within current org.""" - if not org_id: - org_id = self._get_current_org_id() - if not user_id: - env = ServerEnv() - try: - user_id = await env.get_user() - except: - user_id = 'anonymous' - - dbname = self._get_dbname() - - async with DBPools().sqlorContext(dbname) as sor: - sql = """SELECT * FROM product_type_config - WHERE category_id = ${category_id}$ - AND org_id = ${org_id}$ - AND enabled_flg = '1' - AND (operator_id = ${user_id}$ OR operator_id = '0') - ORDER BY created_at DESC""" - rows = await sor.sqlExe(sql, { - 'category_id': category_id, - 'org_id': org_id, - 'user_id': user_id - }) - - configs = [] - for r in (rows or []): - r = dict(r) - config_json = r.get('config_json', '') - if config_json: - try: - r['config_parsed'] = json.loads(config_json) - except: - r['config_parsed'] = {} - configs.append(r) - - return {'success': True, 'configs': configs} - - async def set_operator_config(self, category_id, config_name, config_json, org_id=None, user_id=None): - """Create or update operator configuration within current org.""" - if not org_id: - org_id = self._get_current_org_id() - if not user_id: - env = ServerEnv() - try: - user_id = await env.get_user() - except: - return {'success': False, 'message': 'User not authenticated'} - - if not config_name: - return {'success': False, 'message': 'Missing config_name'} - - dbname = self._get_dbname() - now = time.strftime('%Y-%m-%d %H:%M:%S') - - try: - json.loads(config_json) - except: - return {'success': False, 'message': 'Invalid config_json format'} - - async with DBPools().sqlorContext(dbname) as sor: - # Verify category belongs to org - cat_check = await sor.sqlExe( - "SELECT id FROM product_category WHERE id = ${category_id}$ AND org_id = ${org_id}$", - {'category_id': category_id, 'org_id': org_id} - ) - if not cat_check: - return {'success': False, 'message': 'Category not found or no access'} - - existing = await sor.sqlExe( - """SELECT id FROM product_type_config - WHERE category_id = ${category_id}$ - AND org_id = ${org_id}$ - AND operator_id = ${user_id}$ - AND config_name = ${config_name}$""", - {'category_id': category_id, 'org_id': org_id, - 'user_id': user_id, 'config_name': config_name} - ) - - if existing: - config_id = existing[0]['id'] - await sor.U('product_type_config', { - 'id': config_id, - 'config_json': config_json, - 'updated_at': now - }) - return {'success': True, 'id': config_id, 'message': 'Config updated'} - else: - config_id = getID() - await sor.C('product_type_config', { - 'id': config_id, - 'operator_id': user_id, - 'org_id': org_id, - 'category_id': category_id, - 'config_name': config_name, - 'config_json': config_json, - 'enabled_flg': '1', - 'created_by': user_id, - 'created_at': now, - 'updated_at': now - }) - return {'success': True, 'id': config_id, 'message': 'Config created'} - # ─── Resource Binding ─── async def bind_resource(self, product_id, resource_type, resource_ref_id, diff --git a/scripts/load_path.py b/scripts/load_path.py index 469f9d3..100b45b 100644 --- a/scripts/load_path.py +++ b/scripts/load_path.py @@ -57,15 +57,12 @@ PATHS_LOGINED = [ # Feature pages f"/{MOD}/category_manage.ui", f"/{MOD}/product_manage.ui", - f"/{MOD}/product_type_config_manage.ui", # CRUD alias directories (directory path + index.ui path) f"/{MOD}/product_category_tree", f"/{MOD}/product_category_tree/index.ui", f"/{MOD}/product_list", f"/{MOD}/product_list/index.ui", - f"/{MOD}/product_type_config_list", - f"/{MOD}/product_type_config_list/index.ui", # API endpoints (.dspy) f"/{MOD}/api/category_options.dspy", @@ -79,9 +76,6 @@ PATHS_LOGINED = [ f"/{MOD}/api/product_detail.dspy", f"/{MOD}/api/product_purchase.dspy", f"/{MOD}/api/product_use.dspy", - f"/{MOD}/api/product_type_config_create.dspy", - f"/{MOD}/api/product_type_config_update.dspy", - f"/{MOD}/api/product_type_config_delete.dspy", # CRUD auto-generated .dspy f"/{MOD}/product_category_tree/get_product_category.dspy", @@ -92,10 +86,6 @@ PATHS_LOGINED = [ f"/{MOD}/product_list/add_product.dspy", f"/{MOD}/product_list/update_product.dspy", f"/{MOD}/product_list/delete_product.dspy", - f"/{MOD}/product_type_config_list/get_product_type_config.dspy", - f"/{MOD}/product_type_config_list/add_product_type_config.dspy", - f"/{MOD}/product_type_config_list/update_product_type_config.dspy", - f"/{MOD}/product_type_config_list/delete_product_type_config.dspy", # Resource binding f"/{MOD}/product_resource_list", diff --git a/wwwroot/api/product_detail.dspy b/wwwroot/api/product_detail.dspy index ff1d1d4..beaa7ab 100644 --- a/wwwroot/api/product_detail.dspy +++ b/wwwroot/api/product_detail.dspy @@ -6,11 +6,10 @@ product_code: 产品编码 (可选) org_id: 机构ID (可选,不传则用当前用户机构) 返回: - {success, data: {product_info, category_info, operator_config, extra_parsed}} + {success, data: {product_info, category_info, extra_parsed}} 说明: product_info 包含产品全部信息 extra_parsed 是 extra_json 解析后的结构化数据 - operator_config 是当前运营商对该产品类型的配置 """ import json @@ -63,36 +62,12 @@ try: extra_parsed = {'_raw': extra_str} product_info['extra_parsed'] = extra_parsed - # Get operator config for this product_type - config_sql = """SELECT * FROM product_type_config - WHERE category_id = ${category_id}$ - AND enabled_flg = '1' - AND org_id = ${org_id}$ - AND (operator_id = ${user_id}$ OR operator_id = '0') - ORDER BY created_at DESC LIMIT 1""" - config_rows = await sor.sqlExe(config_sql, { - 'category_id': product_info['category_id'], - 'org_id': org_id, - 'user_id': user_id - }) - - operator_config = {} - if config_rows: - operator_config = dict(config_rows[0]) - config_json = operator_config.get('config_json', '') - if config_json: - try: - operator_config['config_parsed'] = json.loads(config_json) - except: - operator_config['config_parsed'] = {} - result['data'] = { 'product_info': product_info, 'category_info': { 'name': product_info.get('category_name'), 'description': product_info.get('category_description') - }, - 'operator_config': operator_config + } } result['success'] = True diff --git a/wwwroot/api/product_type_config_create.dspy b/wwwroot/api/product_type_config_create.dspy deleted file mode 100644 index 59c91c9..0000000 --- a/wwwroot/api/product_type_config_create.dspy +++ /dev/null @@ -1,26 +0,0 @@ -result = {'widgettype': 'Message', 'options': {'title': 'Error', 'message': 'Invalid', 'type': 'error'}} - -try: - user_id = await get_user() - org_id = (await get_userorgid()) or '0' - - dbname = get_module_dbname('product_management') - data = dict(params_kw) - data['id'] = getID() - data['operator_id'] = user_id - data['org_id'] = org_id - data['created_by'] = user_id - data['created_at'] = timestampstr() - data['updated_at'] = timestampstr() - if 'enabled_flg' not in data: - data['enabled_flg'] = '1' - - async with DBPools().sqlorContext(dbname) as sor: - await sor.C('product_type_config', data) - - result = {'widgettype': 'Message', 'options': {'title': 'Success', 'message': '配置创建成功', 'type': 'success'}} - -except Exception as e: - result['options'] = {'title': 'Error', 'message': '创建失败: ' + str(e), 'type': 'error'} - -return json.dumps(result, ensure_ascii=False) diff --git a/wwwroot/api/product_type_config_delete.dspy b/wwwroot/api/product_type_config_delete.dspy deleted file mode 100644 index a54e443..0000000 --- a/wwwroot/api/product_type_config_delete.dspy +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env python3 -import json - -result = {'widgettype': 'Message', 'options': {'title': 'Error', 'message': 'Invalid', 'type': 'error'}} - -try: - user_id = await get_user() - org_id = (await get_userorgid()) or '0' - - dbname = get_module_dbname('product_management') - data = dict(params_kw) - record_id = data.get('id') - if not record_id: - raise ValueError('Missing id') - - async with DBPools().sqlorContext(dbname) as sor: - check = await sor.sqlExe( - "SELECT id FROM product_type_config WHERE id = ${id}$ AND org_id = ${org_id}$", - {'id': record_id, 'org_id': org_id} - ) - if not check: - raise ValueError('无权删除该记录') - - await sor.D('product_type_config', {'id': record_id, 'org_id': org_id}) - - result = {'widgettype': 'Message', 'options': {'title': 'Success', 'message': '配置删除成功', 'type': 'success'}} - -except Exception as e: - result['options'] = {'title': 'Error', 'message': '删除失败: ' + str(e), 'type': 'error'} - -return json.dumps(result, ensure_ascii=False) diff --git a/wwwroot/api/product_type_config_update.dspy b/wwwroot/api/product_type_config_update.dspy deleted file mode 100644 index 810e1f9..0000000 --- a/wwwroot/api/product_type_config_update.dspy +++ /dev/null @@ -1,32 +0,0 @@ -result = {'widgettype': 'Message', 'options': {'title': 'Error', 'message': 'Invalid', 'type': 'error'}} - -try: - user_id = await get_user() - org_id = (await get_userorgid()) or '0' - - dbname = get_module_dbname('product_management') - data = dict(params_kw) - record_id = data.pop('id', None) - if not record_id: - raise ValueError('Missing id') - - async with DBPools().sqlorContext(dbname) as sor: - check = await sor.sqlExe( - "SELECT id FROM product_type_config WHERE id = ${id}$ AND org_id = ${org_id}$", - {'id': record_id, 'org_id': org_id} - ) - if not check: - raise ValueError('无权操作该记录') - - data['updated_at'] = timestampstr() - data['id'] = record_id - - async with DBPools().sqlorContext(dbname) as sor: - await sor.U('product_type_config', data) - - result = {'widgettype': 'Message', 'options': {'title': 'Success', 'message': '配置更新成功', 'type': 'success'}} - -except Exception as e: - result['options'] = {'title': 'Error', 'message': '更新失败: ' + str(e), 'type': 'error'} - -return json.dumps(result, ensure_ascii=False) diff --git a/wwwroot/index.ui b/wwwroot/index.ui index 5dd7f22..2996a4b 100644 --- a/wwwroot/index.ui +++ b/wwwroot/index.ui @@ -28,7 +28,7 @@ { "widgettype": "Text", "options": { - "text": "产品类别、产品信息与运营商配置管理", + "text": "产品类别与产品信息管理", "fontSize": "14px" } } @@ -113,42 +113,6 @@ } } ] - }, - { - "widgettype": "VBox", - "options": { - "padding": "16px 24px", - "borderRadius": "8px", - "cursor": "pointer" - }, - "binds": [ - { - "wid": "self", - "event": "click", - "actiontype": "urlwidget", - "target": "app.product_content", - "options": { - "url": "{{entire_url('product_type_config_list')}}" - }, - "mode": "replace" - } - ], - "subwidgets": [ - { - "widgettype": "Title5", - "options": { - "text": "运营商配置", - "fontWeight": "600" - } - }, - { - "widgettype": "Text", - "options": { - "text": "配置运营商产品类型参数", - "fontSize": "12px" - } - } - ] } ] }, diff --git a/wwwroot/menu.ui b/wwwroot/menu.ui index 0a401fd..8ebfa74 100644 --- a/wwwroot/menu.ui +++ b/wwwroot/menu.ui @@ -11,8 +11,7 @@ {"name": "resource", "label": "产品资源绑定", "url": "{{entire_url('/product_management/product_resource_list')}}"}, {"name": "supplier", "label": "资源供应商关联", "url": "{{entire_url('/product_management/product_resource_supplier_list')}}"}, {"name": "subscription", "label": "客户订购管理", "url": "{{entire_url('/product_management/product_subscription_list')}}"}, - {"name": "usage", "label": "产品消费记录", "url": "{{entire_url('/product_management/product_usage_log_list')}}"}, - {"name": "config", "label": "运营商配置", "url": "{{entire_url('/product_management/product_type_config_list')}}"} + {"name": "usage", "label": "产品消费记录", "url": "{{entire_url('/product_management/product_usage_log_list')}}"} {% endif %} ] } diff --git a/wwwroot/product_type_config_list/add_product_type_config.dspy b/wwwroot/product_type_config_list/add_product_type_config.dspy deleted file mode 100644 index 9277f4c..0000000 --- a/wwwroot/product_type_config_list/add_product_type_config.dspy +++ /dev/null @@ -1,67 +0,0 @@ - -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['operator_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['org_id'] = userorgid -ns['created_at'] = timestampstr() -ns['updated_at'] = timestampstr() - -db = DBPools() -dbname = get_module_dbname('product_management') -async with db.sqlorContext(dbname) as sor: - r = await sor.C('product_type_config', ns.copy()) - return { - "widgettype":"Message", - "options":{ - "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/product_type_config_list/delete_product_type_config.dspy b/wwwroot/product_type_config_list/delete_product_type_config.dspy deleted file mode 100644 index 813a4d3..0000000 --- a/wwwroot/product_type_config_list/delete_product_type_config.dspy +++ /dev/null @@ -1,61 +0,0 @@ - -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['operator_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['org_id'] = userorgid - -db = DBPools() -dbname = get_module_dbname('product_management') -async with db.sqlorContext(dbname) as sor: - r = await sor.D('product_type_config', 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/product_type_config_list/get_product_type_config.dspy b/wwwroot/product_type_config_list/get_product_type_config.dspy deleted file mode 100644 index 6df93a9..0000000 --- a/wwwroot/product_type_config_list/get_product_type_config.dspy +++ /dev/null @@ -1,148 +0,0 @@ - -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['operator_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['org_id'] = userorgid -ns['userorgid'] = userorgid - -debug(f'get_product_type_config.dspy:{ns=}') -if not ns.get('page'): - ns['page'] = 1 -if not ns.get('sort'): - - - ns['sort'] = ["created_at desc"] - - - -sql = '''select a.*, b.category_id_text, c.enabled_flg_text -from (select * from product_type_config where 1=1 [[filterstr]]) a left join (select id as category_id, - name as category_id_text from product_category where has_product='1' AND status='1') b on a.category_id = b.category_id left join (select k as enabled_flg, - v as enabled_flg_text from appcodes_kv where id='enabled_flg') c on a.enabled_flg = c.enabled_flg''' - -filterjson = params_kw.get('data_filter') -fields_str=r'''[ - { - "name": "id", - "title": "主键ID", - "type": "str", - "length": 32, - "nullable": "no" - }, - { - "name": "operator_id", - "title": "运营商用户ID", - "type": "str", - "length": 32, - "nullable": "no" - }, - { - "name": "org_id", - "title": "所属机构ID", - "type": "str", - "length": 32, - "nullable": "no" - }, - { - "name": "category_id", - "title": "产品类别ID", - "type": "str", - "length": 32, - "nullable": "no" - }, - { - "name": "config_name", - "title": "配置名称", - "type": "str", - "length": 255, - "nullable": "no" - }, - { - "name": "config_json", - "title": "配置内容", - "type": "text" - }, - { - "name": "enabled_flg", - "title": "是否启用", - "type": "char", - "length": 1, - "default": "1" - }, - { - "name": "created_by", - "title": "创建人", - "type": "str", - "length": 32 - }, - { - "name": "created_at", - "title": "创建时间", - "type": "datetime", - "nullable": "no" - }, - { - "name": "updated_at", - "title": "更新时间", - "type": "datetime", - "nullable": "no" - } -]''' -ori_fields = json.loads(fields_str) -if not filterjson: - fields = [ f['name'] for f in ori_fields ] - 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('product_management') -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/product_type_config_list/index.ui b/wwwroot/product_type_config_list/index.ui deleted file mode 100644 index e7b0122..0000000 --- a/wwwroot/product_type_config_list/index.ui +++ /dev/null @@ -1,227 +0,0 @@ -{ - "widgettype": "VBox", - "options": { - "css": "filler", "height": "100%", - "width": "100%" - }, - "subwidgets": [ -{ - "id":"product_type_config_tbl", - "widgettype":"Tabular", - "options":{ - "width":"100%", - "height":"100%", - - - "title":"运营商产品类型配置", - - - - - "css":"card", - - - "editable":{ - - "new_data_url":"{{entire_url('add_product_type_config.dspy')}}", - - - "delete_data_url":"{{entire_url('delete_product_type_config.dspy')}}", - - - "update_data_url":"{{entire_url('update_product_type_config.dspy')}}" - - }, - - - "data_url":"{{entire_url('./get_product_type_config.dspy')}}", - - "data_method":"GET", - "data_params":{{json.dumps(params_kw, indent=4, ensure_ascii=False)}}, - "row_options":{ - - - - "browserfields": { - "exclouded": [], - "alters": { - "category_id": { - "uitype": "code", - "dataurl": "{{entire_url('../api/category_options.dspy')}}", - "datamethod": "GET" - }, - "enabled_flg": { - "uitype": "code", - "data": [ - { - "value": "1", - "text": "启用" - }, - { - "value": "0", - "text": "禁用" - } - ] - } - } -}, - - - "editexclouded":[ - "operator_id", - "created_by", - "created_at", - "updated_at" -], - - "fields":[ - { - "name": "id", - "title": "主键ID", - "type": "str", - "length": 32, - "nullable": "no", - "cwidth": 18, - "uitype": "str", - "datatype": "str", - "label": "主键ID" - }, - { - "name": "operator_id", - "title": "运营商用户ID", - "type": "str", - "length": 32, - "nullable": "no", - "cwidth": 18, - "uitype": "str", - "datatype": "str", - "label": "运营商用户ID" - }, - { - "name": "org_id", - "title": "所属机构ID", - "type": "str", - "length": 32, - "nullable": "no", - "cwidth": 18, - "uitype": "str", - "datatype": "str", - "label": "所属机构ID" - }, - { - "name": "category_id", - "title": "产品类别ID", - "type": "str", - "length": 32, - "nullable": "no", - "label": "产品类别ID", - "uitype": "code", - "valueField": "category_id", - "textField": "category_id_text", - "params": { - "dbname": "{{get_module_dbname('product_management')}}", - "table": "product_category", - "tblvalue": "id", - "tbltext": "name", - "valueField": "category_id", - "textField": "category_id_text", - "cond": "has_product='1' AND status='1'" - }, - "dataurl": "{{entire_url('../api/category_options.dspy')}}", - "datamethod": "GET" - }, - { - "name": "config_name", - "title": "配置名称", - "type": "str", - "length": 255, - "nullable": "no", - "cwidth": 18, - "uitype": "str", - "datatype": "str", - "label": "配置名称" - }, - { - "name": "config_json", - "title": "配置内容", - "type": "text", - "length": 0, - "uitype": "text", - "datatype": "text", - "label": "配置内容" - }, - { - "name": "enabled_flg", - "title": "是否启用", - "type": "char", - "length": 1, - "default": "1", - "label": "是否启用", - "uitype": "code", - "valueField": "enabled_flg", - "textField": "enabled_flg_text", - "params": { - "dbname": "{{get_module_dbname('product_management')}}", - "table": "appcodes_kv", - "tblvalue": "k", - "tbltext": "v", - "valueField": "enabled_flg", - "textField": "enabled_flg_text", - "cond": "id='enabled_flg'" - }, - "dataurl": "{{entire_url('/appbase/get_code.dspy')}}", - "data": [ - { - "value": "1", - "text": "启用" - }, - { - "value": "0", - "text": "禁用" - } - ] - }, - { - "name": "created_by", - "title": "创建人", - "type": "str", - "length": 32, - "cwidth": 18, - "uitype": "str", - "datatype": "str", - "label": "创建人" - }, - { - "name": "created_at", - "title": "创建时间", - "type": "datetime", - "nullable": "no", - "length": 0, - "uitype": "str", - "datatype": "datetime", - "label": "创建时间" - }, - { - "name": "updated_at", - "title": "更新时间", - "type": "datetime", - "nullable": "no", - "length": 0, - "uitype": "str", - "datatype": "datetime", - "label": "更新时间" - } -] - }, - - - - "page_rows":160, - "cache_limit":5 - } - - ,"binds":[] - -} - ] -} diff --git a/wwwroot/product_type_config_list/update_product_type_config.dspy b/wwwroot/product_type_config_list/update_product_type_config.dspy deleted file mode 100644 index c6c399d..0000000 --- a/wwwroot/product_type_config_list/update_product_type_config.dspy +++ /dev/null @@ -1,87 +0,0 @@ - -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['operator_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['org_id'] = userorgid -ns['updated_at'] = timestampstr() - - - -db = DBPools() -dbname = get_module_dbname('product_management') -async with db.sqlorContext(dbname) as sor: - - ns1 = { - - "org_id": userorgid, - - - "operator_id": userid, - - "id": params_kw.id - } - recs = await sor.R('product_type_config', 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('product_type_config', 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 diff --git a/wwwroot/product_type_config_manage.ui b/wwwroot/product_type_config_manage.ui deleted file mode 100644 index 26bc620..0000000 --- a/wwwroot/product_type_config_manage.ui +++ /dev/null @@ -1,16 +0,0 @@ -{ - "widgettype": "VBox", - "options": {"width": "100%", "height": "100%", "padding": "16px"}, - "subwidgets": [ - { - "widgettype": "Text", - "options": {"text": "运营商产品类型配置", "fontSize": "20px", "fontWeight": "bold", "marginBottom": "16px"} - }, - { - "widgettype": "Html", - "options": { - "html": "" - } - } - ] -}