From a807e8d7ee2c8b113863c757f0dbb65636793b06 Mon Sep 17 00:00:00 2001 From: ymq Date: Sat, 8 Aug 2026 17:06:20 +0800 Subject: [PATCH] chore: sync xls2ui generated CRUD files (sd_org_settings, sd_project_repos) --- .../sd_org_settings/add_sd_org_settings.dspy | 55 ++++++ .../delete_sd_org_settings.dspy | 47 +++++ .../sd_org_settings/get_sd_org_settings.dspy | 115 +++++++++++++ wwwroot/sd_org_settings/index.ui | 135 +++++++++++++++ .../update_sd_org_settings.dspy | 78 +++++++++ .../add_sd_project_repos.dspy | 55 ++++++ .../delete_sd_project_repos.dspy | 47 +++++ .../get_sd_project_repos.dspy | 133 ++++++++++++++ wwwroot/sd_project_repos/index.ui | 162 ++++++++++++++++++ .../update_sd_project_repos.dspy | 78 +++++++++ 10 files changed, 905 insertions(+) create mode 100644 wwwroot/sd_org_settings/add_sd_org_settings.dspy create mode 100644 wwwroot/sd_org_settings/delete_sd_org_settings.dspy create mode 100644 wwwroot/sd_org_settings/get_sd_org_settings.dspy create mode 100644 wwwroot/sd_org_settings/index.ui create mode 100644 wwwroot/sd_org_settings/update_sd_org_settings.dspy create mode 100644 wwwroot/sd_project_repos/add_sd_project_repos.dspy create mode 100644 wwwroot/sd_project_repos/delete_sd_project_repos.dspy create mode 100644 wwwroot/sd_project_repos/get_sd_project_repos.dspy create mode 100644 wwwroot/sd_project_repos/index.ui create mode 100644 wwwroot/sd_project_repos/update_sd_project_repos.dspy diff --git a/wwwroot/sd_org_settings/add_sd_org_settings.dspy b/wwwroot/sd_org_settings/add_sd_org_settings.dspy new file mode 100644 index 0000000..66078a8 --- /dev/null +++ b/wwwroot/sd_org_settings/add_sd_org_settings.dspy @@ -0,0 +1,55 @@ + +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 + + + +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('pipeline-sdlc') +async with db.sqlorContext(dbname) as sor: + r = await sor.C('sd_org_settings', ns.copy()) + _new_rows = await sor.sqlExe("SELECT * FROM sd_org_settings WHERE None = ${id}$", {'id': id}) + _user_data = _new_rows[0] if _new_rows else ns + return { + "widgettype":"Message", + "options":{ + "cwidth":16, + "cheight":9, + "title":"Add Success", + "timeout":3, + "message":"ok", + "user_data": _user_data + } + } + +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/sd_org_settings/delete_sd_org_settings.dspy b/wwwroot/sd_org_settings/delete_sd_org_settings.dspy new file mode 100644 index 0000000..88148f7 --- /dev/null +++ b/wwwroot/sd_org_settings/delete_sd_org_settings.dspy @@ -0,0 +1,47 @@ + +ns = { + 'id':params_kw['id'], +} + + +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('pipeline-sdlc') +async with db.sqlorContext(dbname) as sor: + r = await sor.D('sd_org_settings', 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/sd_org_settings/get_sd_org_settings.dspy b/wwwroot/sd_org_settings/get_sd_org_settings.dspy new file mode 100644 index 0000000..40a7253 --- /dev/null +++ b/wwwroot/sd_org_settings/get_sd_org_settings.dspy @@ -0,0 +1,115 @@ + +ns = params_kw.copy() + + +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_sd_org_settings.dspy:{ns=}') +if not ns.get('page'): + ns['page'] = 1 +if not ns.get('sort'): + + + ns['sort'] = ["created_at desc"] + + + +sql = '''select * from sd_org_settings where 1=1 [[filterstr]]''' + + +filterjson = None +fields_str=r'''[ + { + "name": "id", + "title": "主键ID", + "type": "str", + "length": 32, + "nullable": "no" + }, + { + "name": "org_id", + "title": "组织ID", + "type": "str", + "length": 32, + "nullable": "no" + }, + { + "name": "workspace_root", + "title": "工作空间根路径", + "type": "str", + "length": 500, + "nullable": "no" + }, + { + "name": "skills_dir", + "title": "企业Skills目录", + "type": "str", + "length": 500 + }, + { + "name": "created_at", + "title": "创建时间", + "type": "timestamp", + "nullable": "no" + }, + { + "name": "updated_at", + "title": "更新时间", + "type": "timestamp" + } +]''' +ori_fields = json.loads(fields_str) +fields = [ f['name'] for f in ori_fields ] +filterjson = default_filterjson(fields, ns) + + +# 确保 logined 过滤条件始终生效 +if filterjson: + if not isinstance(filterjson, dict) or 'AND' not in filterjson: + filterjson = {'AND': [filterjson] if filterjson else []} + + filterjson['AND'].append({'field': 'org_id', 'op': '=', 'var': '__logined_orgid__'}) + ns['__logined_orgid__'] = userorgid + + + +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('pipeline-sdlc') +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/sd_org_settings/index.ui b/wwwroot/sd_org_settings/index.ui new file mode 100644 index 0000000..9c51b75 --- /dev/null +++ b/wwwroot/sd_org_settings/index.ui @@ -0,0 +1,135 @@ + +{ + "widgettype":"VBox", + "options":{"height":"100%","width":"100%"}, + "subwidgets":[ +{ + "id":"sd_org_settings_tbl", + "widgettype":"Tabular", + "options":{ + "width":"100%", + "height":"100%", + + + "title":"组织SDLC设置", + + + + + "css":"card", + + + "editable":{ + + "new_data_url":"{{entire_url('add_sd_org_settings.dspy')}}", + + + "delete_data_url":"{{entire_url('delete_sd_org_settings.dspy')}}", + + + "update_data_url":"{{entire_url('update_sd_org_settings.dspy')}}" + + + }, + + + "data_url":"{{entire_url('./get_sd_org_settings.dspy')}}", + + "data_method":"GET", + "data_params":{{json.dumps(params_kw, indent=4, ensure_ascii=False)}}, + "row_options":{ + + + + "browserfields": { + "exclouded": [] +}, + + + "editexclouded":[ + "id", + "created_at", + "updated_at", + "org_id" +], + + "fields":[ + { + "name": "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": "workspace_root", + "title": "工作空间根路径", + "type": "str", + "length": 500, + "nullable": "no", + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "工作空间根路径" + }, + { + "name": "skills_dir", + "title": "企业Skills目录", + "type": "str", + "length": 500, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "企业Skills目录" + }, + { + "name": "created_at", + "title": "创建时间", + "type": "timestamp", + "nullable": "no", + "length": 0, + "uitype": "str", + "datatype": "timestamp", + "label": "创建时间" + }, + { + "name": "updated_at", + "title": "更新时间", + "type": "timestamp", + "length": 0, + "uitype": "str", + "datatype": "timestamp", + "label": "更新时间" + } +] + }, + + + + + + + + "page_rows":160, + "cache_limit":5 + } + + ,"binds":[] + +}] +} \ No newline at end of file diff --git a/wwwroot/sd_org_settings/update_sd_org_settings.dspy b/wwwroot/sd_org_settings/update_sd_org_settings.dspy new file mode 100644 index 0000000..4d2a30b --- /dev/null +++ b/wwwroot/sd_org_settings/update_sd_org_settings.dspy @@ -0,0 +1,78 @@ + +ns = params_kw.copy() +for k,v in list(ns.items()): + if v == 'NaN' or v == 'null' or v == '' or v is None: + if k != 'id': + del ns[k] + else: + ns[k] = None if v in ('NaN', 'null') else v + + +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('pipeline-sdlc') +async with db.sqlorContext(dbname) as sor: + + ns1 = { + + "org_id": userorgid, + + + "id": params_kw.id + } + recs = await sor.R('sd_org_settings', 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" + } + } + + tblfields = [{"name":"id","title":"主键ID","type":"str","length":32,"nullable":"no"},{"name":"org_id","title":"组织ID","type":"str","length":32,"nullable":"no"},{"name":"workspace_root","title":"工作空间根路径","type":"str","length":500,"nullable":"no"},{"name":"skills_dir","title":"企业Skills目录","type":"str","length":500},{"name":"created_at","title":"创建时间","type":"timestamp","nullable":"no"},{"name":"updated_at","title":"更新时间","type":"timestamp"}] + tblfname = [ f['name'] for f in tblfields ] + other_keys = [ k for k in ns.keys() if k in tblfname and k != 'id' ] + if len(other_keys) > 0: + r = await sor.U('sd_org_settings', 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/sd_project_repos/add_sd_project_repos.dspy b/wwwroot/sd_project_repos/add_sd_project_repos.dspy new file mode 100644 index 0000000..a70a60d --- /dev/null +++ b/wwwroot/sd_project_repos/add_sd_project_repos.dspy @@ -0,0 +1,55 @@ + +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 + + + +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('pipeline-sdlc') +async with db.sqlorContext(dbname) as sor: + r = await sor.C('sd_project_repos', ns.copy()) + _new_rows = await sor.sqlExe("SELECT * FROM sd_project_repos WHERE None = ${id}$", {'id': id}) + _user_data = _new_rows[0] if _new_rows else ns + return { + "widgettype":"Message", + "options":{ + "cwidth":16, + "cheight":9, + "title":"Add Success", + "timeout":3, + "message":"ok", + "user_data": _user_data + } + } + +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/sd_project_repos/delete_sd_project_repos.dspy b/wwwroot/sd_project_repos/delete_sd_project_repos.dspy new file mode 100644 index 0000000..275c645 --- /dev/null +++ b/wwwroot/sd_project_repos/delete_sd_project_repos.dspy @@ -0,0 +1,47 @@ + +ns = { + 'id':params_kw['id'], +} + + +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('pipeline-sdlc') +async with db.sqlorContext(dbname) as sor: + r = await sor.D('sd_project_repos', 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/sd_project_repos/get_sd_project_repos.dspy b/wwwroot/sd_project_repos/get_sd_project_repos.dspy new file mode 100644 index 0000000..1da1122 --- /dev/null +++ b/wwwroot/sd_project_repos/get_sd_project_repos.dspy @@ -0,0 +1,133 @@ + +ns = params_kw.copy() + + +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_sd_project_repos.dspy:{ns=}') +if not ns.get('page'): + ns['page'] = 1 +if not ns.get('sort'): + + + ns['sort'] = ["created_at desc"] + + + +sql = '''select * from sd_project_repos where 1=1 [[filterstr]]''' + + +filterjson = None +fields_str=r'''[ + { + "name": "id", + "title": "主键ID", + "type": "str", + "length": 32, + "nullable": "no" + }, + { + "name": "project_id", + "title": "项目ID", + "type": "str", + "length": 32, + "nullable": "no" + }, + { + "name": "repo_name", + "title": "仓库别名", + "type": "str", + "length": 100, + "nullable": "no" + }, + { + "name": "repo_url", + "title": "Git地址", + "type": "str", + "length": 500, + "nullable": "no" + }, + { + "name": "default_branch", + "title": "默认分支", + "type": "str", + "length": 100, + "nullable": "no", + "default": "'main'" + }, + { + "name": "local_path", + "title": "本地相对路径", + "type": "str", + "length": 200 + }, + { + "name": "org_id", + "title": "组织ID", + "type": "str", + "length": 32, + "nullable": "no", + "default": "'0'" + }, + { + "name": "created_at", + "title": "创建时间", + "type": "timestamp", + "nullable": "no" + } +]''' +ori_fields = json.loads(fields_str) +fields = [ f['name'] for f in ori_fields ] +filterjson = default_filterjson(fields, ns) + + +# 确保 logined 过滤条件始终生效 +if filterjson: + if not isinstance(filterjson, dict) or 'AND' not in filterjson: + filterjson = {'AND': [filterjson] if filterjson else []} + + filterjson['AND'].append({'field': 'org_id', 'op': '=', 'var': '__logined_orgid__'}) + ns['__logined_orgid__'] = userorgid + + + +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('pipeline-sdlc') +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/sd_project_repos/index.ui b/wwwroot/sd_project_repos/index.ui new file mode 100644 index 0000000..bc593c6 --- /dev/null +++ b/wwwroot/sd_project_repos/index.ui @@ -0,0 +1,162 @@ + +{ + "widgettype":"VBox", + "options":{"height":"100%","width":"100%"}, + "subwidgets":[ +{ + "id":"sd_project_repos_tbl", + "widgettype":"Tabular", + "options":{ + "width":"100%", + "height":"100%", + + + "title":"项目代码仓库", + + + + + "css":"card", + + + "editable":{ + + "new_data_url":"{{entire_url('add_sd_project_repos.dspy')}}", + + + "delete_data_url":"{{entire_url('delete_sd_project_repos.dspy')}}", + + + "update_data_url":"{{entire_url('update_sd_project_repos.dspy')}}" + + + }, + + + "data_url":"{{entire_url('./get_sd_project_repos.dspy')}}", + + "data_method":"GET", + "data_params":{{json.dumps(params_kw, indent=4, ensure_ascii=False)}}, + "row_options":{ + + + + "browserfields": { + "exclouded": [ + "org_id" + ] +}, + + + "editexclouded":[ + "id", + "created_at", + "org_id" +], + + "fields":[ + { + "name": "id", + "title": "主键ID", + "type": "str", + "length": 32, + "nullable": "no", + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "主键ID" + }, + { + "name": "project_id", + "title": "项目ID", + "type": "str", + "length": 32, + "nullable": "no", + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "项目ID" + }, + { + "name": "repo_name", + "title": "仓库别名", + "type": "str", + "length": 100, + "nullable": "no", + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "仓库别名" + }, + { + "name": "repo_url", + "title": "Git地址", + "type": "str", + "length": 500, + "nullable": "no", + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "Git地址" + }, + { + "name": "default_branch", + "title": "默认分支", + "type": "str", + "length": 100, + "nullable": "no", + "default": "'main'", + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "默认分支" + }, + { + "name": "local_path", + "title": "本地相对路径", + "type": "str", + "length": 200, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "本地相对路径" + }, + { + "name": "org_id", + "title": "组织ID", + "type": "str", + "length": 32, + "nullable": "no", + "default": "'0'", + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "组织ID" + }, + { + "name": "created_at", + "title": "创建时间", + "type": "timestamp", + "nullable": "no", + "length": 0, + "uitype": "str", + "datatype": "timestamp", + "label": "创建时间" + } +] + }, + + + + + + + + "page_rows":160, + "cache_limit":5 + } + + ,"binds":[] + +}] +} \ No newline at end of file diff --git a/wwwroot/sd_project_repos/update_sd_project_repos.dspy b/wwwroot/sd_project_repos/update_sd_project_repos.dspy new file mode 100644 index 0000000..4a406c3 --- /dev/null +++ b/wwwroot/sd_project_repos/update_sd_project_repos.dspy @@ -0,0 +1,78 @@ + +ns = params_kw.copy() +for k,v in list(ns.items()): + if v == 'NaN' or v == 'null' or v == '' or v is None: + if k != 'id': + del ns[k] + else: + ns[k] = None if v in ('NaN', 'null') else v + + +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('pipeline-sdlc') +async with db.sqlorContext(dbname) as sor: + + ns1 = { + + "org_id": userorgid, + + + "id": params_kw.id + } + recs = await sor.R('sd_project_repos', 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" + } + } + + tblfields = [{"name":"id","title":"主键ID","type":"str","length":32,"nullable":"no"},{"name":"project_id","title":"项目ID","type":"str","length":32,"nullable":"no"},{"name":"repo_name","title":"仓库别名","type":"str","length":100,"nullable":"no"},{"name":"repo_url","title":"Git地址","type":"str","length":500,"nullable":"no"},{"name":"default_branch","title":"默认分支","type":"str","length":100,"nullable":"no","default":"'main'"},{"name":"local_path","title":"本地相对路径","type":"str","length":200},{"name":"org_id","title":"组织ID","type":"str","length":32,"nullable":"no","default":"'0'"},{"name":"created_at","title":"创建时间","type":"timestamp","nullable":"no"}] + tblfname = [ f['name'] for f in tblfields ] + other_keys = [ k for k in ns.keys() if k in tblfname and k != 'id' ] + if len(other_keys) > 0: + r = await sor.U('sd_project_repos', 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