diff --git a/json/userrole.json b/json/userrole.json index a6f4ec4..b3d172b 100644 --- a/json/userrole.json +++ b/json/userrole.json @@ -8,8 +8,8 @@ "roleid": { "uitype": "code", "dataurl": "{{entire_url('/rbac/api/get_search_roleid.dspy')}}", - "valueField": "value", - "textField": "text" + "valueField": "roleid", + "textField": "roleid_text" } } }, diff --git a/wwwroot/api/get_search_roleid.dspy b/wwwroot/api/get_search_roleid.dspy index 102ec31..447c27e 100644 --- a/wwwroot/api/get_search_roleid.dspy +++ b/wwwroot/api/get_search_roleid.dspy @@ -8,7 +8,7 @@ async with get_sor_context(request._run_ns, 'rbac') as sor: "AND orgtypeid IS NOT NULL AND name IS NOT NULL " "ORDER BY orgtypeid, name", {}) - result = [{'value': '', 'text': '全部'}] + result = [{'roleid': '', 'roleid_text': '全部'}] for r in recs: - result.append({'value': r.id, 'text': r.name}) + result.append({'roleid': r.id, 'roleid_text': r.name}) return result diff --git a/wwwroot/organization/add_organization.dspy b/wwwroot/organization/add_organization.dspy new file mode 100644 index 0000000..fd07f69 --- /dev/null +++ b/wwwroot/organization/add_organization.dspy @@ -0,0 +1,38 @@ + +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 + + + +db = DBPools() +dbname = get_module_dbname('rbac') +async with db.sqlorContext(dbname) as sor: + r = await sor.C('organization', 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/organization/delete_organization.dspy b/wwwroot/organization/delete_organization.dspy new file mode 100644 index 0000000..49692c9 --- /dev/null +++ b/wwwroot/organization/delete_organization.dspy @@ -0,0 +1,33 @@ + +ns = { + 'id':params_kw['id'], +} + + +db = DBPools() +dbname = get_module_dbname('rbac') +async with db.sqlorContext(dbname) as sor: + r = await sor.D('organization', 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/organization/get_organization.dspy b/wwwroot/organization/get_organization.dspy new file mode 100644 index 0000000..84184b9 --- /dev/null +++ b/wwwroot/organization/get_organization.dspy @@ -0,0 +1,160 @@ + +ns = params_kw.copy() + + +debug(f'get_organization.dspy:{ns=}') +if not ns.get('page'): + ns['page'] = 1 +if not ns.get('sort'): + + + ns['sort'] = 'orgname' + + + +sql = '''select a.*, b.province_id_text, c.city_id_text, d.distinct_id_text +from (select * from organization where 1=1 [[filterstr]]) a left join (select k as province_id, + v as province_id_text from appcodes_kv where parentid='chnaddr') b on a.province_id = b.province_id left join (select k as city_id, + v as city_id_text from appcodes_kv where parentid='city') c on a.city_id = c.city_id left join (select k as distinct_id, + v as distinct_id_text from appcodes_kv where parentid='distinct') d on a.distinct_id = d.distinct_id''' + +filterjson = params_kw.get('data_filter') +if not filterjson: + fields = [ f['name'] for f in [ + { + "name": "id", + "title": "机构编码", + "type": "str", + "length": 32 + }, + { + "name": "orgname", + "title": "机构名称", + "type": "str", + "length": 255 + }, + { + "name": "orgabbr", + "title": "机构简称", + "type": "str", + "length": 100 + }, + { + "name": "alias_name", + "title": "机构别名", + "type": "str", + "length": 255 + }, + { + "name": "contactor", + "title": "联系人", + "type": "str", + "length": 32 + }, + { + "name": "contactor_phone", + "title": "联系人电话", + "type": "str", + "length": 100 + }, + { + "name": "province_id", + "title": "所在省id", + "type": "str", + "length": 32 + }, + { + "name": "city_id", + "title": "所在城市id", + "type": "str", + "length": 32 + }, + { + "name": "distinct_id", + "title": "所在地区id", + "type": "str", + "length": 32 + }, + { + "name": "emailaddress", + "title": "邮箱", + "type": "str", + "length": 256 + }, + { + "name": "address", + "title": "地址", + "type": "str", + "length": 400 + }, + { + "name": "main_business", + "title": "主营业务描述", + "type": "str", + "length": 1000 + }, + { + "name": "orgcode", + "title": "组织结构代码", + "type": "str", + "length": 100 + }, + { + "name": "license_img", + "title": "营业执照", + "type": "str", + "length": 400 + }, + { + "name": "id_img", + "title": "身份证", + "type": "str", + "length": 400 + }, + { + "name": "parentid", + "title": "父机构id", + "type": "str", + "length": 32 + }, + { + "name": "org_type", + "title": "机构类型", + "type": "str", + "length": 32 + }, + { + "name": "sitename", + "title": "网站域名", + "type": "str", + "length": 300 + } +] ] + 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('rbac') +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/organization/index.ui b/wwwroot/organization/index.ui new file mode 100644 index 0000000..034dac3 --- /dev/null +++ b/wwwroot/organization/index.ui @@ -0,0 +1,329 @@ + +{ + "id":"organization_tbl", + "widgettype":"Tabular", + "options":{ + "width":"100%", + "height":"100%", + + + "title":"机构", + + + + + "toolbar":{ + "tools": [ + { + "selected_row": true, + "name": "orgtypes", + "icon": "{{entire_url('/imgs/orgtypes.svg')}}", + "label": "类型管理" + } + ] +}, + + "css":"card", + + "editor":{ + "binds": [ + { + "wid": "province_id", + "event": "changed", + "actiontype": "script", + "target": "city_id", + "script": "this.loadData({cond:'parentid=\\''+params.province_id+'\\''})" + }, + { + "wid": "city_id", + "event": "changed", + "actiontype": "script", + "target": "distinct_id", + "script": "this.loadData({cond:'parentid=\\'' + params.city_id+ '\\''})" + } + ] +}, + + + "editable":{ + + "new_data_url":"{{entire_url('add_organization.dspy')}}", + + + "delete_data_url":"{{entire_url('delete_organization.dspy')}}", + + + "update_data_url":"{{entire_url('update_organization.dspy')}}" + + }, + + + "data_url":"{{entire_url('./get_organization.dspy')}}", + + "data_method":"GET", + "data_params":{{json.dumps(params_kw, indent=4, ensure_ascii=False)}}, + "row_options":{ + + + + "browserfields": { + "exclouded": [ + "id" + ], + "alters": {} +}, + + + "editexclouded":[ + "id" +], + + "fields":[ + { + "name": "id", + "title": "机构编码", + "type": "str", + "length": 32, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "机构编码" + }, + { + "name": "orgname", + "title": "机构名称", + "type": "str", + "length": 255, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "机构名称" + }, + { + "name": "orgabbr", + "title": "机构简称", + "type": "str", + "length": 100, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "机构简称" + }, + { + "name": "alias_name", + "title": "机构别名", + "type": "str", + "length": 255, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "机构别名" + }, + { + "name": "contactor", + "title": "联系人", + "type": "str", + "length": 32, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "联系人" + }, + { + "name": "contactor_phone", + "title": "联系人电话", + "type": "str", + "length": 100, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "联系人电话" + }, + { + "name": "province_id", + "title": "所在省id", + "type": "str", + "length": 32, + "label": "所在省id", + "uitype": "code", + "valueField": "province_id", + "textField": "province_id_text", + "params": { + "dbname": "{{get_module_dbname('rbac')}}", + "table": "appcodes_kv", + "tblvalue": "k", + "tbltext": "v", + "valueField": "province_id", + "textField": "province_id_text", + "cond": "parentid='chnaddr'" + }, + "dataurl": "{{entire_url('/appbase/get_code.dspy')}}" + }, + { + "name": "city_id", + "title": "所在城市id", + "type": "str", + "length": 32, + "label": "所在城市id", + "uitype": "code", + "valueField": "city_id", + "textField": "city_id_text", + "params": { + "dbname": "{{get_module_dbname('rbac')}}", + "table": "appcodes_kv", + "tblvalue": "k", + "tbltext": "v", + "valueField": "city_id", + "textField": "city_id_text", + "cond": "parentid='city'" + }, + "dataurl": "{{entire_url('/appbase/get_code.dspy')}}" + }, + { + "name": "distinct_id", + "title": "所在地区id", + "type": "str", + "length": 32, + "label": "所在地区id", + "uitype": "code", + "valueField": "distinct_id", + "textField": "distinct_id_text", + "params": { + "dbname": "{{get_module_dbname('rbac')}}", + "table": "appcodes_kv", + "tblvalue": "k", + "tbltext": "v", + "valueField": "distinct_id", + "textField": "distinct_id_text", + "cond": "parentid='distinct'" + }, + "dataurl": "{{entire_url('/appbase/get_code.dspy')}}" + }, + { + "name": "emailaddress", + "title": "邮箱", + "type": "str", + "length": 256, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "邮箱" + }, + { + "name": "address", + "title": "地址", + "type": "str", + "length": 400, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "地址" + }, + { + "name": "main_business", + "title": "主营业务描述", + "type": "str", + "length": 1000, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "主营业务描述" + }, + { + "name": "orgcode", + "title": "组织结构代码", + "type": "str", + "length": 100, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "组织结构代码" + }, + { + "name": "license_img", + "title": "营业执照", + "type": "str", + "length": 400, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "营业执照" + }, + { + "name": "id_img", + "title": "身份证", + "type": "str", + "length": 400, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "身份证" + }, + { + "name": "parentid", + "title": "父机构id", + "type": "str", + "length": 32, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "父机构id" + }, + { + "name": "org_type", + "title": "机构类型", + "type": "str", + "length": 32, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "机构类型" + }, + { + "name": "sitename", + "title": "网站域名", + "type": "str", + "length": 300, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "网站域名" + } +] + }, + + + + "page_rows":160, + "cache_limit":5 + } + + ,"binds":[ + { + "wid": "self", + "event": "orgtypes", + "actiontype": "urlwidget", + "target": "PopupWindow", + "popup_options": { + "title": "类型管理", + "icon": "{{entire_url('/appbase/get_icon.dspy')}}?id=orgtypes", + "resizable": true, + "height": "70%", + "width": "70%" + }, + "params_mapping": { + "mapping": { + "id": "orgid", + "referer_widget": "referer_widget" + }, + "need_other": false + }, + "options": { + "method": "POST", + "params": {}, + "url": "../orgtypes" + } + } +] + +} \ No newline at end of file diff --git a/wwwroot/organization/update_organization.dspy b/wwwroot/organization/update_organization.dspy new file mode 100644 index 0000000..fda3409 --- /dev/null +++ b/wwwroot/organization/update_organization.dspy @@ -0,0 +1,36 @@ + +ns = params_kw.copy() +for k,v in ns.items(): + if v == 'NaN' or v == 'null': + ns[k] = None + + + + +db = DBPools() +dbname = get_module_dbname('rbac') +async with db.sqlorContext(dbname) as sor: + + r = await sor.U('organization', 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/orgtypes/add_orgtypes.dspy b/wwwroot/orgtypes/add_orgtypes.dspy new file mode 100644 index 0000000..99e8d1f --- /dev/null +++ b/wwwroot/orgtypes/add_orgtypes.dspy @@ -0,0 +1,38 @@ + +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 + + + +db = DBPools() +dbname = get_module_dbname('rbac') +async with db.sqlorContext(dbname) as sor: + r = await sor.C('orgtypes', 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/orgtypes/delete_orgtypes.dspy b/wwwroot/orgtypes/delete_orgtypes.dspy new file mode 100644 index 0000000..c8387c7 --- /dev/null +++ b/wwwroot/orgtypes/delete_orgtypes.dspy @@ -0,0 +1,33 @@ + +ns = { + 'id':params_kw['id'], +} + + +db = DBPools() +dbname = get_module_dbname('rbac') +async with db.sqlorContext(dbname) as sor: + r = await sor.D('orgtypes', 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/orgtypes/get_orgtypes.dspy b/wwwroot/orgtypes/get_orgtypes.dspy new file mode 100644 index 0000000..b853e79 --- /dev/null +++ b/wwwroot/orgtypes/get_orgtypes.dspy @@ -0,0 +1,66 @@ + +ns = params_kw.copy() + + +debug(f'get_orgtypes.dspy:{ns=}') +if not ns.get('page'): + ns['page'] = 1 +if not ns.get('sort'): + + ns['sort'] = 'id' + + +sql = '''select a.*, b.orgtypeid_text +from (select * from orgtypes where 1=1 [[filterstr]]) a left join (select k as orgtypeid, + v as orgtypeid_text from appcodes_kv where parentid='org_type') b on a.orgtypeid = b.orgtypeid''' + +filterjson = params_kw.get('data_filter') +if not filterjson: + fields = [ f['name'] for f in [ + { + "name": "id", + "title": "id", + "type": "str", + "length": 32 + }, + { + "name": "orgid", + "title": "机构id", + "type": "str", + "length": 32 + }, + { + "name": "orgtypeid", + "title": "机构类型", + "type": "str", + "length": 32 + } +] ] + 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('rbac') +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/orgtypes/index.ui b/wwwroot/orgtypes/index.ui new file mode 100644 index 0000000..3229ee1 --- /dev/null +++ b/wwwroot/orgtypes/index.ui @@ -0,0 +1,106 @@ + +{ + "id":"orgtypes_tbl", + "widgettype":"Tabular", + "options":{ + "width":"100%", + "height":"100%", + + + "title":"机构拥有角色", + + + + + "css":"card", + + + "editable":{ + + "new_data_url":"{{entire_url('add_orgtypes.dspy')}}", + + + "delete_data_url":"{{entire_url('delete_orgtypes.dspy')}}", + + + "update_data_url":"{{entire_url('update_orgtypes.dspy')}}" + + }, + + + "data_url":"{{entire_url('./get_orgtypes.dspy')}}", + + "data_method":"GET", + "data_params":{{json.dumps(params_kw, indent=4, ensure_ascii=False)}}, + "row_options":{ + + + + "browserfields": { + "exclouded": [ + "id", + "orgid" + ], + "cwidth": {}, + "alters": null +}, + + + "editexclouded":[ + "id", + "orgid" +], + + "fields":[ + { + "name": "id", + "title": "id", + "type": "str", + "length": 32, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "id" + }, + { + "name": "orgid", + "title": "机构id", + "type": "str", + "length": 32, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "机构id" + }, + { + "name": "orgtypeid", + "title": "机构类型", + "type": "str", + "length": 32, + "label": "机构类型", + "uitype": "code", + "valueField": "orgtypeid", + "textField": "orgtypeid_text", + "params": { + "dbname": "{{get_module_dbname('rbac')}}", + "table": "appcodes_kv", + "tblvalue": "k", + "tbltext": "v", + "valueField": "orgtypeid", + "textField": "orgtypeid_text", + "cond": "parentid='org_type'" + }, + "dataurl": "{{entire_url('/appbase/get_code.dspy')}}" + } +] + }, + + + + "page_rows":160, + "cache_limit":5 + } + + ,"binds":[] + +} \ No newline at end of file diff --git a/wwwroot/orgtypes/update_orgtypes.dspy b/wwwroot/orgtypes/update_orgtypes.dspy new file mode 100644 index 0000000..58bd77d --- /dev/null +++ b/wwwroot/orgtypes/update_orgtypes.dspy @@ -0,0 +1,36 @@ + +ns = params_kw.copy() +for k,v in ns.items(): + if v == 'NaN' or v == 'null': + ns[k] = None + + + + +db = DBPools() +dbname = get_module_dbname('rbac') +async with db.sqlorContext(dbname) as sor: + + r = await sor.U('orgtypes', 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/permission/delete_permission.dspy b/wwwroot/permission/delete_permission.dspy new file mode 100644 index 0000000..61f490a --- /dev/null +++ b/wwwroot/permission/delete_permission.dspy @@ -0,0 +1,33 @@ + +ns = { + 'id':params_kw['id'], +} + + +db = DBPools() +dbname = get_module_dbname('rbac') +async with db.sqlorContext(dbname) as sor: + r = await sor.D('permission', 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/permission/get_permission.dspy b/wwwroot/permission/get_permission.dspy new file mode 100644 index 0000000..f90d9bf --- /dev/null +++ b/wwwroot/permission/get_permission.dspy @@ -0,0 +1,16 @@ + +ns = params_kw.copy() +sql = '''select * from permission where 1 = 1''' +id = ns.get('id') +if id: + sql += " and parentid = ${id}$" +else: + sql += " and parentid is null" + +sql += " order by path " +db = DBPools() +dbname = get_module_dbname('rbac') +async with db.sqlorContext(dbname) as sor: + r = await sor.sqlExe(sql, ns) + return r +return [] \ No newline at end of file diff --git a/wwwroot/permission/index.ui b/wwwroot/permission/index.ui new file mode 100644 index 0000000..cb1e460 --- /dev/null +++ b/wwwroot/permission/index.ui @@ -0,0 +1,122 @@ + +{ + "widgettype":"Tree", + "options":{ + "width":"100%", + "height":"100%", + + + "title":"权限", + + + + + + "editable":{ + "fields":[ + { + "name": "name", + "title": "名称", + "type": "str", + "length": 255, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "名称" + }, + { + "name": "description", + "title": "描述", + "type": "str", + "length": 255, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "描述" + }, + { + "name": "path", + "title": "路径", + "type": "str", + "length": 255, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "路径" + }, + { + "name": "icon", + "title": "图标", + "type": "str", + "length": 255, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "图标" + }, + { + "name": "permtype", + "title": "类型", + "type": "str", + "length": 255, + "label": "类型", + "uitype": "code", + "valueField": "permtype", + "textField": "permtype_text", + "params": { + "dbname": "{{get_module_dbname('rbac')}}", + "table": "appcodes_kv", + "tblvalue": "k", + "tbltext": "v", + "valueField": "permtype", + "textField": "permtype_text", + "cond": "parentid='permtype'" + }, + "dataurl": "{{entire_url('/appbase/get_code.dspy')}}" + }, + { + "name": "need_audit", + "title": "是否审计", + "type": "str", + "length": 1, + "label": "是否审计", + "uitype": "code", + "valueField": "need_audit", + "textField": "need_audit_text", + "params": { + "dbname": "{{get_module_dbname('rbac')}}", + "table": "appcodes_kv", + "tblvalue": "k", + "tbltext": "v", + "valueField": "need_audit", + "textField": "need_audit_text", + "cond": "parentid='yesno'" + }, + "dataurl": "{{entire_url('/appbase/get_code.dspy')}}" + } +], + + "add_url":"{{entire_url('./new_permission.dspy')}}", + + + "update_url":"{{entire_url('./update_permission.dspy')}}", + + + "delete_url":"{{entire_url('./delete_permission.dspy')}}" + + }, + + + "parentField":"parentid", + "idField":"id", + "textField":"path", + + + + + + "dataurl":"{{entire_url('./get_permission.dspy')}}" + + } + +} \ No newline at end of file diff --git a/wwwroot/permission/new_permission.dspy b/wwwroot/permission/new_permission.dspy new file mode 100644 index 0000000..2be364b --- /dev/null +++ b/wwwroot/permission/new_permission.dspy @@ -0,0 +1,38 @@ + +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 + + + +db = DBPools() +dbname = get_module_dbname('rbac') +async with db.sqlorContext(dbname) as sor: + r = await sor.C('permission', 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/permission/update_permission.dspy b/wwwroot/permission/update_permission.dspy new file mode 100644 index 0000000..d33b3e2 --- /dev/null +++ b/wwwroot/permission/update_permission.dspy @@ -0,0 +1,36 @@ + +ns = params_kw.copy() +for k,v in ns.items(): + if v == 'NaN' or v == 'null': + ns[k] = None + + + + +db = DBPools() +dbname = get_module_dbname('rbac') +async with db.sqlorContext(dbname) as sor: + + r = await sor.U('permission', 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/provider/add_organization.dspy b/wwwroot/provider/add_organization.dspy new file mode 100644 index 0000000..fd07f69 --- /dev/null +++ b/wwwroot/provider/add_organization.dspy @@ -0,0 +1,38 @@ + +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 + + + +db = DBPools() +dbname = get_module_dbname('rbac') +async with db.sqlorContext(dbname) as sor: + r = await sor.C('organization', 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/provider/delete_organization.dspy b/wwwroot/provider/delete_organization.dspy new file mode 100644 index 0000000..49692c9 --- /dev/null +++ b/wwwroot/provider/delete_organization.dspy @@ -0,0 +1,33 @@ + +ns = { + 'id':params_kw['id'], +} + + +db = DBPools() +dbname = get_module_dbname('rbac') +async with db.sqlorContext(dbname) as sor: + r = await sor.D('organization', 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/provider/get_organization.dspy b/wwwroot/provider/get_organization.dspy new file mode 100644 index 0000000..84184b9 --- /dev/null +++ b/wwwroot/provider/get_organization.dspy @@ -0,0 +1,160 @@ + +ns = params_kw.copy() + + +debug(f'get_organization.dspy:{ns=}') +if not ns.get('page'): + ns['page'] = 1 +if not ns.get('sort'): + + + ns['sort'] = 'orgname' + + + +sql = '''select a.*, b.province_id_text, c.city_id_text, d.distinct_id_text +from (select * from organization where 1=1 [[filterstr]]) a left join (select k as province_id, + v as province_id_text from appcodes_kv where parentid='chnaddr') b on a.province_id = b.province_id left join (select k as city_id, + v as city_id_text from appcodes_kv where parentid='city') c on a.city_id = c.city_id left join (select k as distinct_id, + v as distinct_id_text from appcodes_kv where parentid='distinct') d on a.distinct_id = d.distinct_id''' + +filterjson = params_kw.get('data_filter') +if not filterjson: + fields = [ f['name'] for f in [ + { + "name": "id", + "title": "机构编码", + "type": "str", + "length": 32 + }, + { + "name": "orgname", + "title": "机构名称", + "type": "str", + "length": 255 + }, + { + "name": "orgabbr", + "title": "机构简称", + "type": "str", + "length": 100 + }, + { + "name": "alias_name", + "title": "机构别名", + "type": "str", + "length": 255 + }, + { + "name": "contactor", + "title": "联系人", + "type": "str", + "length": 32 + }, + { + "name": "contactor_phone", + "title": "联系人电话", + "type": "str", + "length": 100 + }, + { + "name": "province_id", + "title": "所在省id", + "type": "str", + "length": 32 + }, + { + "name": "city_id", + "title": "所在城市id", + "type": "str", + "length": 32 + }, + { + "name": "distinct_id", + "title": "所在地区id", + "type": "str", + "length": 32 + }, + { + "name": "emailaddress", + "title": "邮箱", + "type": "str", + "length": 256 + }, + { + "name": "address", + "title": "地址", + "type": "str", + "length": 400 + }, + { + "name": "main_business", + "title": "主营业务描述", + "type": "str", + "length": 1000 + }, + { + "name": "orgcode", + "title": "组织结构代码", + "type": "str", + "length": 100 + }, + { + "name": "license_img", + "title": "营业执照", + "type": "str", + "length": 400 + }, + { + "name": "id_img", + "title": "身份证", + "type": "str", + "length": 400 + }, + { + "name": "parentid", + "title": "父机构id", + "type": "str", + "length": 32 + }, + { + "name": "org_type", + "title": "机构类型", + "type": "str", + "length": 32 + }, + { + "name": "sitename", + "title": "网站域名", + "type": "str", + "length": 300 + } +] ] + 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('rbac') +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/provider/index.ui b/wwwroot/provider/index.ui new file mode 100644 index 0000000..98834bd --- /dev/null +++ b/wwwroot/provider/index.ui @@ -0,0 +1,329 @@ + +{ + "id":"organization_tbl", + "widgettype":"Tabular", + "options":{ + "width":"100%", + "height":"100%", + + + "title":"机构", + + + + + "toolbar":{ + "tools": [ + { + "selected_row": true, + "name": "orgtypes", + "icon": "{{entire_url('/imgs/orgtypes.svg')}}", + "label": "机构类型" + } + ] +}, + + "css":"card", + + "editor":{ + "binds": [ + { + "wid": "province_id", + "event": "changed", + "actiontype": "script", + "target": "city_id", + "script": "this.loadData({cond:'parentid=\\''+params.province_id+'\\''})" + }, + { + "wid": "city_id", + "event": "changed", + "actiontype": "script", + "target": "distinct_id", + "script": "this.loadData({cond:'parentid=\\'' + params.city_id+ '\\''})" + } + ] +}, + + + "editable":{ + + "new_data_url":"{{entire_url('add_organization.dspy')}}", + + + "delete_data_url":"{{entire_url('delete_organization.dspy')}}", + + + "update_data_url":"{{entire_url('update_organization.dspy')}}" + + }, + + + "data_url":"{{entire_url('./get_organization.dspy')}}", + + "data_method":"GET", + "data_params":{{json.dumps(params_kw, indent=4, ensure_ascii=False)}}, + "row_options":{ + + + + "browserfields": { + "exclouded": [ + "id" + ], + "alters": {} +}, + + + "editexclouded":[ + "id" +], + + "fields":[ + { + "name": "id", + "title": "机构编码", + "type": "str", + "length": 32, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "机构编码" + }, + { + "name": "orgname", + "title": "机构名称", + "type": "str", + "length": 255, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "机构名称" + }, + { + "name": "orgabbr", + "title": "机构简称", + "type": "str", + "length": 100, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "机构简称" + }, + { + "name": "alias_name", + "title": "机构别名", + "type": "str", + "length": 255, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "机构别名" + }, + { + "name": "contactor", + "title": "联系人", + "type": "str", + "length": 32, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "联系人" + }, + { + "name": "contactor_phone", + "title": "联系人电话", + "type": "str", + "length": 100, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "联系人电话" + }, + { + "name": "province_id", + "title": "所在省id", + "type": "str", + "length": 32, + "label": "所在省id", + "uitype": "code", + "valueField": "province_id", + "textField": "province_id_text", + "params": { + "dbname": "{{get_module_dbname('rbac')}}", + "table": "appcodes_kv", + "tblvalue": "k", + "tbltext": "v", + "valueField": "province_id", + "textField": "province_id_text", + "cond": "parentid='chnaddr'" + }, + "dataurl": "{{entire_url('/appbase/get_code.dspy')}}" + }, + { + "name": "city_id", + "title": "所在城市id", + "type": "str", + "length": 32, + "label": "所在城市id", + "uitype": "code", + "valueField": "city_id", + "textField": "city_id_text", + "params": { + "dbname": "{{get_module_dbname('rbac')}}", + "table": "appcodes_kv", + "tblvalue": "k", + "tbltext": "v", + "valueField": "city_id", + "textField": "city_id_text", + "cond": "parentid='city'" + }, + "dataurl": "{{entire_url('/appbase/get_code.dspy')}}" + }, + { + "name": "distinct_id", + "title": "所在地区id", + "type": "str", + "length": 32, + "label": "所在地区id", + "uitype": "code", + "valueField": "distinct_id", + "textField": "distinct_id_text", + "params": { + "dbname": "{{get_module_dbname('rbac')}}", + "table": "appcodes_kv", + "tblvalue": "k", + "tbltext": "v", + "valueField": "distinct_id", + "textField": "distinct_id_text", + "cond": "parentid='distinct'" + }, + "dataurl": "{{entire_url('/appbase/get_code.dspy')}}" + }, + { + "name": "emailaddress", + "title": "邮箱", + "type": "str", + "length": 256, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "邮箱" + }, + { + "name": "address", + "title": "地址", + "type": "str", + "length": 400, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "地址" + }, + { + "name": "main_business", + "title": "主营业务描述", + "type": "str", + "length": 1000, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "主营业务描述" + }, + { + "name": "orgcode", + "title": "组织结构代码", + "type": "str", + "length": 100, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "组织结构代码" + }, + { + "name": "license_img", + "title": "营业执照", + "type": "str", + "length": 400, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "营业执照" + }, + { + "name": "id_img", + "title": "身份证", + "type": "str", + "length": 400, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "身份证" + }, + { + "name": "parentid", + "title": "父机构id", + "type": "str", + "length": 32, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "父机构id" + }, + { + "name": "org_type", + "title": "机构类型", + "type": "str", + "length": 32, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "机构类型" + }, + { + "name": "sitename", + "title": "网站域名", + "type": "str", + "length": 300, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "网站域名" + } +] + }, + + + + "page_rows":160, + "cache_limit":5 + } + + ,"binds":[ + { + "wid": "self", + "event": "orgtypes", + "actiontype": "urlwidget", + "target": "PopupWindow", + "popup_options": { + "title": "机构类型", + "icon": "{{entire_url('/appbase/get_icon.dspy')}}?id=orgtypes", + "resizable": true, + "height": "70%", + "width": "70%" + }, + "params_mapping": { + "mapping": { + "id": "orgid", + "referer_widget": "referer_widget" + }, + "need_other": false + }, + "options": { + "method": "POST", + "params": {}, + "url": "{{entire_url('../orgtypes')}}" + } + } +] + +} \ No newline at end of file diff --git a/wwwroot/provider/update_organization.dspy b/wwwroot/provider/update_organization.dspy new file mode 100644 index 0000000..fda3409 --- /dev/null +++ b/wwwroot/provider/update_organization.dspy @@ -0,0 +1,36 @@ + +ns = params_kw.copy() +for k,v in ns.items(): + if v == 'NaN' or v == 'null': + ns[k] = None + + + + +db = DBPools() +dbname = get_module_dbname('rbac') +async with db.sqlorContext(dbname) as sor: + + r = await sor.U('organization', 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/reseller/add_organization.dspy b/wwwroot/reseller/add_organization.dspy new file mode 100644 index 0000000..fd07f69 --- /dev/null +++ b/wwwroot/reseller/add_organization.dspy @@ -0,0 +1,38 @@ + +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 + + + +db = DBPools() +dbname = get_module_dbname('rbac') +async with db.sqlorContext(dbname) as sor: + r = await sor.C('organization', 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/reseller/delete_organization.dspy b/wwwroot/reseller/delete_organization.dspy new file mode 100644 index 0000000..49692c9 --- /dev/null +++ b/wwwroot/reseller/delete_organization.dspy @@ -0,0 +1,33 @@ + +ns = { + 'id':params_kw['id'], +} + + +db = DBPools() +dbname = get_module_dbname('rbac') +async with db.sqlorContext(dbname) as sor: + r = await sor.D('organization', 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/reseller/get_organization.dspy b/wwwroot/reseller/get_organization.dspy new file mode 100644 index 0000000..84184b9 --- /dev/null +++ b/wwwroot/reseller/get_organization.dspy @@ -0,0 +1,160 @@ + +ns = params_kw.copy() + + +debug(f'get_organization.dspy:{ns=}') +if not ns.get('page'): + ns['page'] = 1 +if not ns.get('sort'): + + + ns['sort'] = 'orgname' + + + +sql = '''select a.*, b.province_id_text, c.city_id_text, d.distinct_id_text +from (select * from organization where 1=1 [[filterstr]]) a left join (select k as province_id, + v as province_id_text from appcodes_kv where parentid='chnaddr') b on a.province_id = b.province_id left join (select k as city_id, + v as city_id_text from appcodes_kv where parentid='city') c on a.city_id = c.city_id left join (select k as distinct_id, + v as distinct_id_text from appcodes_kv where parentid='distinct') d on a.distinct_id = d.distinct_id''' + +filterjson = params_kw.get('data_filter') +if not filterjson: + fields = [ f['name'] for f in [ + { + "name": "id", + "title": "机构编码", + "type": "str", + "length": 32 + }, + { + "name": "orgname", + "title": "机构名称", + "type": "str", + "length": 255 + }, + { + "name": "orgabbr", + "title": "机构简称", + "type": "str", + "length": 100 + }, + { + "name": "alias_name", + "title": "机构别名", + "type": "str", + "length": 255 + }, + { + "name": "contactor", + "title": "联系人", + "type": "str", + "length": 32 + }, + { + "name": "contactor_phone", + "title": "联系人电话", + "type": "str", + "length": 100 + }, + { + "name": "province_id", + "title": "所在省id", + "type": "str", + "length": 32 + }, + { + "name": "city_id", + "title": "所在城市id", + "type": "str", + "length": 32 + }, + { + "name": "distinct_id", + "title": "所在地区id", + "type": "str", + "length": 32 + }, + { + "name": "emailaddress", + "title": "邮箱", + "type": "str", + "length": 256 + }, + { + "name": "address", + "title": "地址", + "type": "str", + "length": 400 + }, + { + "name": "main_business", + "title": "主营业务描述", + "type": "str", + "length": 1000 + }, + { + "name": "orgcode", + "title": "组织结构代码", + "type": "str", + "length": 100 + }, + { + "name": "license_img", + "title": "营业执照", + "type": "str", + "length": 400 + }, + { + "name": "id_img", + "title": "身份证", + "type": "str", + "length": 400 + }, + { + "name": "parentid", + "title": "父机构id", + "type": "str", + "length": 32 + }, + { + "name": "org_type", + "title": "机构类型", + "type": "str", + "length": 32 + }, + { + "name": "sitename", + "title": "网站域名", + "type": "str", + "length": 300 + } +] ] + 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('rbac') +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/reseller/index.ui b/wwwroot/reseller/index.ui new file mode 100644 index 0000000..51ddb8e --- /dev/null +++ b/wwwroot/reseller/index.ui @@ -0,0 +1,360 @@ + +{ + "id":"organization_tbl", + "widgettype":"Tabular", + "options":{ + "width":"100%", + "height":"100%", + + + "title":"机构", + + + + + "toolbar":{ + "tools": [ + { + "selected_row": true, + "name": "orgtypes", + "icon": "{{entire_url('/imgs/orgtypes.svg')}}", + "label": "机构类型" + }, + { + "selected_row": true, + "name": "users", + "icon": "{{entire_url('/imgs/users.svg')}}", + "label": "用户" + } + ] +}, + + "css":"card", + + "editor":{ + "binds": [ + { + "wid": "province_id", + "event": "changed", + "actiontype": "script", + "target": "city_id", + "script": "this.loadData({cond:'parentid=\\''+params.province_id+'\\''})" + }, + { + "wid": "city_id", + "event": "changed", + "actiontype": "script", + "target": "distinct_id", + "script": "this.loadData({cond:'parentid=\\'' + params.city_id+ '\\''})" + } + ] +}, + + + "editable":{ + + "new_data_url": "{{entire_url('../add_reseller.dspy')}}", + + + "delete_data_url":"{{entire_url('delete_organization.dspy')}}", + + + "update_data_url":"{{entire_url('update_organization.dspy')}}" + + }, + + + "data_url": "{{entire_url('../get_reseller.dspy')}}", + + "data_method":"GET", + "data_params":{{json.dumps(params_kw, indent=4, ensure_ascii=False)}}, + "row_options":{ + + + + "browserfields": { + "exclouded": [ + "id" + ], + "alters": {} +}, + + + "editexclouded":[ + "id" +], + + "fields":[ + { + "name": "id", + "title": "机构编码", + "type": "str", + "length": 32, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "机构编码" + }, + { + "name": "orgname", + "title": "机构名称", + "type": "str", + "length": 255, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "机构名称" + }, + { + "name": "orgabbr", + "title": "机构简称", + "type": "str", + "length": 100, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "机构简称" + }, + { + "name": "alias_name", + "title": "机构别名", + "type": "str", + "length": 255, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "机构别名" + }, + { + "name": "contactor", + "title": "联系人", + "type": "str", + "length": 32, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "联系人" + }, + { + "name": "contactor_phone", + "title": "联系人电话", + "type": "str", + "length": 100, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "联系人电话" + }, + { + "name": "province_id", + "title": "所在省id", + "type": "str", + "length": 32, + "label": "所在省id", + "uitype": "code", + "valueField": "province_id", + "textField": "province_id_text", + "params": { + "dbname": "{{get_module_dbname('rbac')}}", + "table": "appcodes_kv", + "tblvalue": "k", + "tbltext": "v", + "valueField": "province_id", + "textField": "province_id_text", + "cond": "parentid='chnaddr'" + }, + "dataurl": "{{entire_url('/appbase/get_code.dspy')}}" + }, + { + "name": "city_id", + "title": "所在城市id", + "type": "str", + "length": 32, + "label": "所在城市id", + "uitype": "code", + "valueField": "city_id", + "textField": "city_id_text", + "params": { + "dbname": "{{get_module_dbname('rbac')}}", + "table": "appcodes_kv", + "tblvalue": "k", + "tbltext": "v", + "valueField": "city_id", + "textField": "city_id_text", + "cond": "parentid='city'" + }, + "dataurl": "{{entire_url('/appbase/get_code.dspy')}}" + }, + { + "name": "distinct_id", + "title": "所在地区id", + "type": "str", + "length": 32, + "label": "所在地区id", + "uitype": "code", + "valueField": "distinct_id", + "textField": "distinct_id_text", + "params": { + "dbname": "{{get_module_dbname('rbac')}}", + "table": "appcodes_kv", + "tblvalue": "k", + "tbltext": "v", + "valueField": "distinct_id", + "textField": "distinct_id_text", + "cond": "parentid='distinct'" + }, + "dataurl": "{{entire_url('/appbase/get_code.dspy')}}" + }, + { + "name": "emailaddress", + "title": "邮箱", + "type": "str", + "length": 256, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "邮箱" + }, + { + "name": "address", + "title": "地址", + "type": "str", + "length": 400, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "地址" + }, + { + "name": "main_business", + "title": "主营业务描述", + "type": "str", + "length": 1000, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "主营业务描述" + }, + { + "name": "orgcode", + "title": "组织结构代码", + "type": "str", + "length": 100, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "组织结构代码" + }, + { + "name": "license_img", + "title": "营业执照", + "type": "str", + "length": 400, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "营业执照" + }, + { + "name": "id_img", + "title": "身份证", + "type": "str", + "length": 400, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "身份证" + }, + { + "name": "parentid", + "title": "父机构id", + "type": "str", + "length": 32, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "父机构id" + }, + { + "name": "org_type", + "title": "机构类型", + "type": "str", + "length": 32, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "机构类型" + }, + { + "name": "sitename", + "title": "网站域名", + "type": "str", + "length": 300, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "网站域名" + } +] + }, + + + + "page_rows":160, + "cache_limit":5 + } + + ,"binds":[ + { + "wid": "self", + "event": "orgtypes", + "actiontype": "urlwidget", + "target": "PopupWindow", + "popup_options": { + "title": "机构类型", + "icon": "{{entire_url('/appbase/get_icon.dspy')}}?id=orgtypes", + "resizable": true, + "height": "70%", + "width": "70%" + }, + "params_mapping": { + "mapping": { + "id": "orgid", + "referer_widget": "referer_widget" + }, + "need_other": false + }, + "options": { + "method": "POST", + "params": {}, + "url": "{{entire_url('../orgtypes')}}" + } + }, + { + "wid": "self", + "event": "users", + "actiontype": "urlwidget", + "target": "PopupWindow", + "popup_options": { + "title": "用户", + "icon": "{{entire_url('/appbase/get_icon.dspy')}}?id=users", + "resizable": true, + "height": "70%", + "width": "70%" + }, + "params_mapping": { + "mapping": { + "id": "orgid", + "referer_widget": "referer_widget" + }, + "need_other": false + }, + "options": { + "method": "POST", + "params": {}, + "url": "{{entire_url('../users')}}" + } + } +] + +} \ No newline at end of file diff --git a/wwwroot/reseller/update_organization.dspy b/wwwroot/reseller/update_organization.dspy new file mode 100644 index 0000000..fda3409 --- /dev/null +++ b/wwwroot/reseller/update_organization.dspy @@ -0,0 +1,36 @@ + +ns = params_kw.copy() +for k,v in ns.items(): + if v == 'NaN' or v == 'null': + ns[k] = None + + + + +db = DBPools() +dbname = get_module_dbname('rbac') +async with db.sqlorContext(dbname) as sor: + + r = await sor.U('organization', 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/role/add_role.dspy b/wwwroot/role/add_role.dspy new file mode 100644 index 0000000..c900fcc --- /dev/null +++ b/wwwroot/role/add_role.dspy @@ -0,0 +1,38 @@ + +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 + + + +db = DBPools() +dbname = get_module_dbname('rbac') +async with db.sqlorContext(dbname) as sor: + r = await sor.C('role', 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/role/delete_role.dspy b/wwwroot/role/delete_role.dspy new file mode 100644 index 0000000..f3798ee --- /dev/null +++ b/wwwroot/role/delete_role.dspy @@ -0,0 +1,33 @@ + +ns = { + 'id':params_kw['id'], +} + + +db = DBPools() +dbname = get_module_dbname('rbac') +async with db.sqlorContext(dbname) as sor: + r = await sor.D('role', 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/role/get_role.dspy b/wwwroot/role/get_role.dspy new file mode 100644 index 0000000..6655707 --- /dev/null +++ b/wwwroot/role/get_role.dspy @@ -0,0 +1,69 @@ + +ns = params_kw.copy() + + +debug(f'get_role.dspy:{ns=}') +if not ns.get('page'): + ns['page'] = 1 +if not ns.get('sort'): + + + ns['sort'] = ["orgtypeid","name"] + + + +sql = '''select a.*, b.orgtypeid_text +from (select * from role where 1=1 [[filterstr]]) a left join (select k as orgtypeid, + v as orgtypeid_text from appcodes_kv where parentid='org_type') b on a.orgtypeid = b.orgtypeid''' + +filterjson = params_kw.get('data_filter') +if not filterjson: + fields = [ f['name'] for f in [ + { + "name": "id", + "title": "角色id", + "type": "str", + "length": 32 + }, + { + "name": "orgtypeid", + "title": "机构类型", + "type": "str", + "length": 32, + "default": "0" + }, + { + "name": "name", + "title": "角色名称", + "type": "str", + "length": 100 + } +] ] + 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('rbac') +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/role/index.ui b/wwwroot/role/index.ui new file mode 100644 index 0000000..2bfeed7 --- /dev/null +++ b/wwwroot/role/index.ui @@ -0,0 +1,173 @@ + +{ + "id":"role_tbl", + "widgettype":"Tabular", + "options":{ + "width":"100%", + "height":"100%", + + + "title":" 角色", + + + + + "toolbar":{ + "tools": [ + { + "selected_row": true, + "name": "rolepermission", + "icon": "{{entire_url('/imgs/rolepermission.svg')}}", + "label": "角色权限" + }, + { + "selected_row": true, + "name": "users", + "icon": "{{entire_url('/imgs/users.svg')}}", + "label": "用户" + } + ] +}, + + "css":"card", + + + "editable":{ + + "new_data_url":"{{entire_url('add_role.dspy')}}", + + + "delete_data_url":"{{entire_url('delete_role.dspy')}}", + + + "update_data_url":"{{entire_url('update_role.dspy')}}" + + }, + + + "data_url":"{{entire_url('./get_role.dspy')}}", + + "data_method":"GET", + "data_params":{{json.dumps(params_kw, indent=4, ensure_ascii=False)}}, + "row_options":{ + + + + "browserfields": { + "exclouded": [ + "id" + ], + "cwidth": {}, + "alters": null +}, + + + "editexclouded":[ + "id" +], + + "fields":[ + { + "name": "id", + "title": "角色id", + "type": "str", + "length": 32, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "角色id" + }, + { + "name": "orgtypeid", + "title": "机构类型", + "type": "str", + "length": 32, + "default": "0", + "label": "机构类型", + "uitype": "code", + "valueField": "orgtypeid", + "textField": "orgtypeid_text", + "params": { + "dbname": "{{get_module_dbname('rbac')}}", + "table": "appcodes_kv", + "tblvalue": "k", + "tbltext": "v", + "valueField": "orgtypeid", + "textField": "orgtypeid_text", + "cond": "parentid='org_type'" + }, + "dataurl": "{{entire_url('/appbase/get_code.dspy')}}" + }, + { + "name": "name", + "title": "角色名称", + "type": "str", + "length": 100, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "角色名称" + } +] + }, + + + + "page_rows":160, + "cache_limit":5 + } + + ,"binds":[ + { + "wid": "self", + "event": "rolepermission", + "actiontype": "urlwidget", + "target": "PopupWindow", + "popup_options": { + "title": "角色权限", + "icon": "{{entire_url('/appbase/get_icon.dspy')}}?id=rolepermission", + "resizable": true, + "height": "70%", + "width": "70%" + }, + "params_mapping": { + "mapping": { + "id": "roleid", + "referer_widget": "referer_widget" + }, + "need_other": false + }, + "options": { + "method": "POST", + "params": {}, + "url": "{{entire_url('../rolepermission')}}" + } + }, + { + "wid": "self", + "event": "users", + "actiontype": "urlwidget", + "target": "PopupWindow", + "popup_options": { + "title": "用户", + "icon": "{{entire_url('/appbase/get_icon.dspy')}}?id=users", + "resizable": true, + "height": "70%", + "width": "70%" + }, + "params_mapping": { + "mapping": { + "id": "roleid", + "referer_widget": "referer_widget" + }, + "need_other": false + }, + "options": { + "method": "POST", + "params": {}, + "url": "{{entire_url('../users')}}" + } + } +] + +} \ No newline at end of file diff --git a/wwwroot/role/update_role.dspy b/wwwroot/role/update_role.dspy new file mode 100644 index 0000000..e14a532 --- /dev/null +++ b/wwwroot/role/update_role.dspy @@ -0,0 +1,36 @@ + +ns = params_kw.copy() +for k,v in ns.items(): + if v == 'NaN' or v == 'null': + ns[k] = None + + + + +db = DBPools() +dbname = get_module_dbname('rbac') +async with db.sqlorContext(dbname) as sor: + + r = await sor.U('role', 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/rolepermission/check_changed.dspy b/wwwroot/rolepermission/check_changed.dspy new file mode 100644 index 0000000..4d2ae77 --- /dev/null +++ b/wwwroot/rolepermission/check_changed.dspy @@ -0,0 +1,40 @@ + +is_checked = params_kw.get('has_roleid') +debug(f'{params_kw=}, {is_checked=}') +dbname = get_module_dbname('rbac') +if is_checked == 'true': + ns = { + "id":uuid(), + "roleid":params_kw.roleid, + "permid":params_kw.permid + } + db = DBPools(); + async with db.sqlorContext(dbname) as sor: + await sor.C('rolepermission', ns) + + return { + "widgettype":"Message", + "options":{ + "title":"Success", + "message":"record add success", + "timeout":2 + } + } +else: + ns = { + "roleid":params_kw.roleid, + "permid":params_kw.permid + } + sql = "delete from rolepermission where roleid=" + "${" + "roleid" + "}$" + " and permid=" + "${" + "permid" + "}$" + db = DBPools() + async with db.sqlorContext(dbname) as sor: + await sor.sqlExe(sql, ns) + + return { + "widgettype":"Message", + "options":{ + "title":"Success", + "message":"delete record success", + "timeout":3 + } + } \ No newline at end of file diff --git a/wwwroot/rolepermission/get_rolepermission.dspy b/wwwroot/rolepermission/get_rolepermission.dspy new file mode 100644 index 0000000..d46d2d0 --- /dev/null +++ b/wwwroot/rolepermission/get_rolepermission.dspy @@ -0,0 +1,33 @@ + +ns = params_kw.copy() + + +debug(f'get_rolepermission.dspy:{ns=}') +if not ns.get('page'): + ns['page'] = 1 +if not ns.get('sort'): + + ns['sort'] = 'id' + + +ns['sort'] = 'permid_text' + +sql = '''select '$[roleid]$' as roleid, +case when b.roleid is NULL then 0 else 1 end has_roleid, +a.id as permid, +a.path as permid_text +from permission a left join +(select * from rolepermission where roleid =${roleid}$) b + on a.id = b.permid +''' + +debug(f'{sql=}') +db = DBPools() +dbname = get_module_dbname('rbac') +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/rolepermission/index.ui b/wwwroot/rolepermission/index.ui new file mode 100644 index 0000000..9bdbd10 --- /dev/null +++ b/wwwroot/rolepermission/index.ui @@ -0,0 +1,119 @@ + +{ + "id":"rolepermission_tbl", + "widgettype":"Tabular", + "options":{ + "width":"100%", + "height":"100%", + + + "title":"角色权限表", + + + + + "css":"card", + + + + "data_url":"{{entire_url('./get_rolepermission.dspy')}}", + + "data_method":"GET", + "data_params":{{json.dumps(params_kw, indent=4, ensure_ascii=False)}}, + "row_options":{ + + + "checkField":"has_roleid", + + + "browserfields": { + "exclouded": [ + "id", + "roleid" + ], + "alters": { + "permid": { + "cwidth": 60 + } + } +}, + + + "editexclouded":[ + "id", + "roleid" +], + + "fields":[ + { + "name": "id", + "title": "id", + "type": "str", + "length": 32, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "id" + }, + { + "name": "roleid", + "title": "角色id", + "type": "str", + "length": 32, + "label": "角色id", + "uitype": "code", + "valueField": "roleid", + "textField": "roleid_text", + "params": { + "dbname": "{{get_module_dbname('rbac')}}", + "table": "(select id, concat(orgtypeid, '.', name) as name from role) as a", + "tblvalue": "id", + "tbltext": "name", + "valueField": "roleid", + "textField": "roleid_text" + }, + "dataurl": "{{entire_url('/appbase/get_code.dspy')}}" + }, + { + "name": "permid", + "title": "权限id", + "type": "str", + "length": 32, + "label": "权限id", + "uitype": "code", + "valueField": "permid", + "textField": "permid_text", + "params": { + "dbname": "{{get_module_dbname('rbac')}}", + "table": "permission", + "tblvalue": "id", + "tbltext": "path", + "valueField": "permid", + "textField": "permid_text" + }, + "dataurl": "{{entire_url('/appbase/get_code.dspy')}}", + "cwidth": 60 + } +] + }, + + + + "page_rows":160, + "cache_limit":5 + } + + ,"binds":[ + { + "wid": "self", + "event": "row_check_changed", + "actiontype": "urlwidget", + "target": "self", + "options": { + "params": {}, + "url": "{{entire_url('check_changed.dspy')}}" + } + } +] + +} \ No newline at end of file diff --git a/wwwroot/userapp/add_userapp.dspy b/wwwroot/userapp/add_userapp.dspy new file mode 100644 index 0000000..9a43ef5 --- /dev/null +++ b/wwwroot/userapp/add_userapp.dspy @@ -0,0 +1,41 @@ + +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 + +if params_kw.get('apikey'): + ns['apikey'] = password_encode(params_kw.get('apikey')) + + + +db = DBPools() +dbname = get_module_dbname('rbac') +async with db.sqlorContext(dbname) as sor: + r = await sor.C('userapp', 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/userapp/delete_userapp.dspy b/wwwroot/userapp/delete_userapp.dspy new file mode 100644 index 0000000..32d172e --- /dev/null +++ b/wwwroot/userapp/delete_userapp.dspy @@ -0,0 +1,33 @@ + +ns = { + 'id':params_kw['id'], +} + + +db = DBPools() +dbname = get_module_dbname('rbac') +async with db.sqlorContext(dbname) as sor: + r = await sor.D('userapp', 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/userapp/get_userapp.dspy b/wwwroot/userapp/get_userapp.dspy new file mode 100644 index 0000000..b7ebfb3 --- /dev/null +++ b/wwwroot/userapp/get_userapp.dspy @@ -0,0 +1,89 @@ + +ns = params_kw.copy() + + +debug(f'get_userapp.dspy:{ns=}') +if not ns.get('page'): + ns['page'] = 1 +if not ns.get('sort'): + + + ns['sort'] = 'appname' + + + +sql = '''select * from userapp where 1=1 [[filterstr]]''' + +filterjson = params_kw.get('data_filter') +if not filterjson: + fields = [ f['name'] for f in [ + { + "name": "id", + "title": "id", + "type": "str", + "length": 32 + }, + { + "name": "userid", + "title": "用户id", + "type": "str", + "length": 32, + "default": "0" + }, + { + "name": "appname", + "title": "应用名称", + "type": "str", + "length": 99 + }, + { + "name": "apikey", + "title": "apikey", + "type": "str", + "length": 400 + }, + { + "name": "enabled_date", + "title": "启用日期", + "type": "date" + }, + { + "name": "expired_date", + "title": "失效日期", + "type": "date" + }, + { + "name": "allowed_ips", + "title": "允许IP集", + "type": "str", + "length": 200 + } +] ] + 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('rbac') +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/userapp/index.ui b/wwwroot/userapp/index.ui new file mode 100644 index 0000000..b7b701d --- /dev/null +++ b/wwwroot/userapp/index.ui @@ -0,0 +1,134 @@ + +{ + "id":"userapp_tbl", + "widgettype":"Tabular", + "options":{ + "width":"100%", + "height":"100%", + + + "title":"用户应用", + + + + + "css":"card", + + + "editable":{ + + "new_data_url":"{{entire_url('add_userapp.dspy')}}", + + + "delete_data_url":"{{entire_url('delete_userapp.dspy')}}", + + + "update_data_url":"{{entire_url('update_userapp.dspy')}}" + + }, + + + "data_url":"{{entire_url('./get_userapp.dspy')}}", + + "data_method":"GET", + "data_params":{{json.dumps(params_kw, indent=4, ensure_ascii=False)}}, + "row_options":{ + + + + "browserfields": { + "exclouded": [ + "id", + "userid" + ], + "alters": {} +}, + + + "editexclouded":[ + "id", + "userid" +], + + "fields":[ + { + "name": "id", + "title": "id", + "type": "str", + "length": 32, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "id" + }, + { + "name": "userid", + "title": "用户id", + "type": "str", + "length": 32, + "default": "0", + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "用户id" + }, + { + "name": "appname", + "title": "应用名称", + "type": "str", + "length": 99, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "应用名称" + }, + { + "name": "apikey", + "title": "apikey", + "type": "str", + "length": 400, + "cwidth": 18, + "uitype": "password", + "datatype": "str", + "label": "apikey" + }, + { + "name": "enabled_date", + "title": "启用日期", + "type": "date", + "length": 0, + "uitype": "date", + "datatype": "date", + "label": "启用日期" + }, + { + "name": "expired_date", + "title": "失效日期", + "type": "date", + "length": 0, + "uitype": "date", + "datatype": "date", + "label": "失效日期" + }, + { + "name": "allowed_ips", + "title": "允许IP集", + "type": "str", + "length": 200, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "允许IP集" + } +] + }, + + + + "page_rows":160, + "cache_limit":5 + } + + ,"binds":[] + +} \ No newline at end of file diff --git a/wwwroot/userapp/update_userapp.dspy b/wwwroot/userapp/update_userapp.dspy new file mode 100644 index 0000000..c05421e --- /dev/null +++ b/wwwroot/userapp/update_userapp.dspy @@ -0,0 +1,39 @@ + +ns = params_kw.copy() +for k,v in ns.items(): + if v == 'NaN' or v == 'null': + ns[k] = None + + + +if params_kw.get('apikey'): + ns['apikey'] = password_encode(params_kw.get('apikey')) + + +db = DBPools() +dbname = get_module_dbname('rbac') +async with db.sqlorContext(dbname) as sor: + + r = await sor.U('userapp', 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/userdepartment/add_userdepartment.dspy b/wwwroot/userdepartment/add_userdepartment.dspy new file mode 100644 index 0000000..f83ecbc --- /dev/null +++ b/wwwroot/userdepartment/add_userdepartment.dspy @@ -0,0 +1,38 @@ + +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 + + + +db = DBPools() +dbname = get_module_dbname('rbac') +async with db.sqlorContext(dbname) as sor: + r = await sor.C('userdepartment', 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/userdepartment/delete_userdepartment.dspy b/wwwroot/userdepartment/delete_userdepartment.dspy new file mode 100644 index 0000000..7e09a46 --- /dev/null +++ b/wwwroot/userdepartment/delete_userdepartment.dspy @@ -0,0 +1,33 @@ + +ns = { + 'id':params_kw['id'], +} + + +db = DBPools() +dbname = get_module_dbname('rbac') +async with db.sqlorContext(dbname) as sor: + r = await sor.D('userdepartment', 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/userdepartment/get_userdepartment.dspy b/wwwroot/userdepartment/get_userdepartment.dspy new file mode 100644 index 0000000..fc1b571 --- /dev/null +++ b/wwwroot/userdepartment/get_userdepartment.dspy @@ -0,0 +1,64 @@ + +ns = params_kw.copy() + + +debug(f'get_userdepartment.dspy:{ns=}') +if not ns.get('page'): + ns['page'] = 1 +if not ns.get('sort'): + + ns['sort'] = 'id' + + +sql = '''select * from userdepartment where 1=1 [[filterstr]]''' + +filterjson = params_kw.get('data_filter') +if not filterjson: + fields = [ f['name'] for f in [ + { + "name": "id", + "title": "id", + "type": "str", + "length": 32 + }, + { + "name": "userid", + "title": "用户id", + "type": "str", + "length": 32 + }, + { + "name": "depid", + "title": "部门id", + "type": "str", + "length": 32 + } +] ] + 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('rbac') +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/userdepartment/index.ui b/wwwroot/userdepartment/index.ui new file mode 100644 index 0000000..4794b2a --- /dev/null +++ b/wwwroot/userdepartment/index.ui @@ -0,0 +1,96 @@ + +{ + "id":"userdepartment_tbl", + "widgettype":"Tabular", + "options":{ + "width":"100%", + "height":"100%", + + + "title":"用户部门表", + + + + + "css":"card", + + + "editable":{ + + "new_data_url":"{{entire_url('add_userdepartment.dspy')}}", + + + "delete_data_url":"{{entire_url('delete_userdepartment.dspy')}}", + + + "update_data_url":"{{entire_url('update_userdepartment.dspy')}}" + + }, + + + "data_url":"{{entire_url('./get_userdepartment.dspy')}}", + + "data_method":"GET", + "data_params":{{json.dumps(params_kw, indent=4, ensure_ascii=False)}}, + "row_options":{ + + + + "browserfields": { + "exclouded": [ + "id", + "userid" + ], + "cwidth": {}, + "alters": null +}, + + + "editexclouded":[ + "id", + "userid" +], + + "fields":[ + { + "name": "id", + "title": "id", + "type": "str", + "length": 32, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "id" + }, + { + "name": "userid", + "title": "用户id", + "type": "str", + "length": 32, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "用户id" + }, + { + "name": "depid", + "title": "部门id", + "type": "str", + "length": 32, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "部门id" + } +] + }, + + + + "page_rows":160, + "cache_limit":5 + } + + ,"binds":[] + +} \ No newline at end of file diff --git a/wwwroot/userdepartment/update_userdepartment.dspy b/wwwroot/userdepartment/update_userdepartment.dspy new file mode 100644 index 0000000..a27b2a8 --- /dev/null +++ b/wwwroot/userdepartment/update_userdepartment.dspy @@ -0,0 +1,36 @@ + +ns = params_kw.copy() +for k,v in ns.items(): + if v == 'NaN' or v == 'null': + ns[k] = None + + + + +db = DBPools() +dbname = get_module_dbname('rbac') +async with db.sqlorContext(dbname) as sor: + + r = await sor.U('userdepartment', 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/userrole/add_userrole.dspy b/wwwroot/userrole/add_userrole.dspy new file mode 100644 index 0000000..499bb69 --- /dev/null +++ b/wwwroot/userrole/add_userrole.dspy @@ -0,0 +1,38 @@ + +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 + + + +db = DBPools() +dbname = get_module_dbname('rbac') +async with db.sqlorContext(dbname) as sor: + r = await sor.C('userrole', 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/userrole/delete_userrole.dspy b/wwwroot/userrole/delete_userrole.dspy new file mode 100644 index 0000000..2ee2cd8 --- /dev/null +++ b/wwwroot/userrole/delete_userrole.dspy @@ -0,0 +1,33 @@ + +ns = { + 'id':params_kw['id'], +} + + +db = DBPools() +dbname = get_module_dbname('rbac') +async with db.sqlorContext(dbname) as sor: + r = await sor.D('userrole', 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/userrole/get_userrole.dspy b/wwwroot/userrole/get_userrole.dspy new file mode 100644 index 0000000..7cf87ba --- /dev/null +++ b/wwwroot/userrole/get_userrole.dspy @@ -0,0 +1,67 @@ + +ns = params_kw.copy() + + +debug(f'get_userrole.dspy:{ns=}') +if not ns.get('page'): + ns['page'] = 1 +if not ns.get('sort'): + + ns['sort'] = 'id' + + +sql = '''select a.*, b.userid_text, c.roleid_text +from (select * from userrole where 1=1 [[filterstr]]) a left join (select id as userid, + username as userid_text from users where 1 = 1) b on a.userid = b.userid left join (select id as roleid, + name as roleid_text from (select id, concat(orgtypeid, '.', name) as name from role) as a where 1 = 1) c on a.roleid = c.roleid''' + +filterjson = params_kw.get('data_filter') +if not filterjson: + fields = [ f['name'] for f in [ + { + "name": "id", + "title": "用户id", + "type": "str", + "length": 32 + }, + { + "name": "userid", + "title": "用户id", + "type": "str", + "length": 32 + }, + { + "name": "roleid", + "title": "角色id", + "type": "str", + "length": 32 + } +] ] + 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('rbac') +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/userrole/index.ui b/wwwroot/userrole/index.ui new file mode 100644 index 0000000..03bc1b8 --- /dev/null +++ b/wwwroot/userrole/index.ui @@ -0,0 +1,120 @@ + +{ + "id":"userrole_tbl", + "widgettype":"Tabular", + "options":{ + "width":"100%", + "height":"100%", + + + "title":"用户角色", + + + + + "css":"card", + + + "editable":{ + + "new_data_url":"{{entire_url('add_userrole.dspy')}}", + + + "delete_data_url":"{{entire_url('delete_userrole.dspy')}}", + + + "update_data_url":"{{entire_url('update_userrole.dspy')}}" + + }, + + + "data_url":"{{entire_url('./get_userrole.dspy')}}", + + "data_method":"GET", + "data_params":{{json.dumps(params_kw, indent=4, ensure_ascii=False)}}, + "row_options":{ + + + + "browserfields": { + "exclouded": [ + "id", + "orgid" + ], + "alters": { + "roleid": { + "uitype": "code", + "dataurl": "{{entire_url('/rbac/api/get_search_roleid.dspy')}}", + "valueField": "roleid", + "textField": "roleid_text" + } + } +}, + + + "editexclouded":[ + "id", + "userid" +], + + "fields":[ + { + "name": "id", + "title": "用户id", + "type": "str", + "length": 32, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "用户id" + }, + { + "name": "userid", + "title": "用户id", + "type": "str", + "length": 32, + "label": "用户id", + "uitype": "code", + "valueField": "userid", + "textField": "userid_text", + "params": { + "dbname": "{{get_module_dbname('rbac')}}", + "table": "users", + "tblvalue": "id", + "tbltext": "username", + "valueField": "userid", + "textField": "userid_text" + }, + "dataurl": "{{entire_url('/appbase/get_code.dspy')}}" + }, + { + "name": "roleid", + "title": "角色id", + "type": "str", + "length": 32, + "label": "角色id", + "uitype": "code", + "valueField": "roleid", + "textField": "roleid_text", + "params": { + "dbname": "{{get_module_dbname('rbac')}}", + "table": "(select id, concat(orgtypeid, '.', name) as name from role) as a", + "tblvalue": "id", + "tbltext": "name", + "valueField": "roleid", + "textField": "roleid_text" + }, + "dataurl": "{{entire_url('/rbac/api/get_search_roleid.dspy')}}" + } +] + }, + + + + "page_rows":160, + "cache_limit":5 + } + + ,"binds":[] + +} \ No newline at end of file diff --git a/wwwroot/userrole/update_userrole.dspy b/wwwroot/userrole/update_userrole.dspy new file mode 100644 index 0000000..02ed6a1 --- /dev/null +++ b/wwwroot/userrole/update_userrole.dspy @@ -0,0 +1,36 @@ + +ns = params_kw.copy() +for k,v in ns.items(): + if v == 'NaN' or v == 'null': + ns[k] = None + + + + +db = DBPools() +dbname = get_module_dbname('rbac') +async with db.sqlorContext(dbname) as sor: + + r = await sor.U('userrole', 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/users/add_users.dspy b/wwwroot/users/add_users.dspy new file mode 100644 index 0000000..74dda4b --- /dev/null +++ b/wwwroot/users/add_users.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 + +if params_kw.get('password'): + ns['password'] = password_encode(params_kw.get('password')) + + + +userorgid = await get_userorgid() +if not userorgid: + return { + "widgettype":"Error", + "options":{ + "title":"Authorization Error", + "timeout":3, + "cwidth":16, + "cheight":9, + "message":"Please login" + } + } +ns['orgid'] = userorgid + +db = DBPools() +dbname = get_module_dbname('rbac') +async with db.sqlorContext(dbname) as sor: + r = await sor.C('users', 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/users/delete_users.dspy b/wwwroot/users/delete_users.dspy new file mode 100644 index 0000000..2a4b3a6 --- /dev/null +++ b/wwwroot/users/delete_users.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['orgid'] = userorgid + +db = DBPools() +dbname = get_module_dbname('rbac') +async with db.sqlorContext(dbname) as sor: + r = await sor.D('users', 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/users/get_users.dspy b/wwwroot/users/get_users.dspy new file mode 100644 index 0000000..b7b3e67 --- /dev/null +++ b/wwwroot/users/get_users.dspy @@ -0,0 +1,152 @@ + +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['orgid'] = userorgid +ns['userorgid'] = userorgid + +debug(f'get_users.dspy:{ns=}') +if not ns.get('page'): + ns['page'] = 1 +if not ns.get('sort'): + + + ns['sort'] = 'username' + + + +sql = '''select a.*, b.user_status_text, c.sync_from_text, d.orgid_text +from (select * from users where 1=1 [[filterstr]]) a left join (select k as user_status, + v as user_status_text from appcodes_kv where parentid='user_status') b on a.user_status = b.user_status left join (select id as sync_from, + name as sync_from_text from downapp where 1 = 1) c on a.sync_from = c.sync_from left join (select id as orgid, + orgname as orgid_text from organization where 1 = 1) d on a.orgid = d.orgid''' + +filterjson = params_kw.get('data_filter') +if not filterjson: + fields = [ f['name'] for f in [ + { + "name": "id", + "title": "用户id", + "type": "str", + "length": 32 + }, + { + "name": "username", + "title": "用户名", + "type": "str", + "length": 255 + }, + { + "name": "password", + "title": "密码", + "type": "str", + "length": 255 + }, + { + "name": "email", + "title": "邮件地址", + "type": "str", + "length": 255 + }, + { + "name": "orgid", + "title": "所属机构", + "type": "str", + "length": 32 + }, + { + "name": "nick_name", + "title": "显示名", + "type": "str", + "length": 255 + }, + { + "name": "address", + "title": "地址", + "type": "str", + "length": 255 + }, + { + "name": "mobile", + "title": "手机", + "type": "str", + "length": 255 + }, + { + "name": "user_status", + "title": "用户状态", + "type": "str", + "length": 1, + "default": "0" + }, + { + "name": "created_at", + "title": "注册日期", + "type": "date" + }, + { + "name": "last_login", + "title": "最后登录", + "type": "timestamp", + "nullable": true + }, + { + "name": "login_fail_count", + "title": "连续失败次数", + "type": "short", + "default": "0" + }, + { + "name": "last_login_fail", + "title": "最后登录失败时间", + "type": "timestamp", + "nullable": true + }, + { + "name": "sync_from", + "title": "同步应用id", + "type": "str", + "length": 32, + "nullable": true + } +] ] + 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('rbac') +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/users/index.ui b/wwwroot/users/index.ui new file mode 100644 index 0000000..3c53025 --- /dev/null +++ b/wwwroot/users/index.ui @@ -0,0 +1,294 @@ + +{ + "id":"users_tbl", + "widgettype":"Tabular", + "options":{ + "width":"100%", + "height":"100%", + + + "title":"用户", + + + + + "toolbar":{ + "tools": [ + { + "selected_row": true, + "name": "userrole", + "icon": "{{entire_url('/imgs/userrole.svg')}}", + "label": "用户角色" + } + ] +}, + + "css":"card", + + + "editable":{ + + "new_data_url": "{{entire_url('/rbac/api/add_user.dspy')}}", + + + "delete_data_url":"{{entire_url('delete_users.dspy')}}", + + + "update_data_url": "{{entire_url('/rbac/api/update_user.dspy')}}" + + }, + + + "data_url":"{{entire_url('./get_users.dspy')}}", + + "data_method":"GET", + "data_params":{{json.dumps(params_kw, indent=4, ensure_ascii=False)}}, + "row_options":{ + + + + "browserfields": { + "exclouded": [ + "id", + "password", + "orgid", + "nick_name" + ], + "cwidth": {}, + "alters": null +}, + + + "editexclouded":[ + "id", + "nick_name", + "orgid", + "last_login_fail", + "last_login", + "sync_from", + "login_fail_count", + "created_at" +], + + "fields":[ + { + "name": "id", + "title": "用户id", + "type": "str", + "length": 32, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "用户id" + }, + { + "name": "username", + "title": "用户名", + "type": "str", + "length": 255, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "用户名" + }, + { + "name": "password", + "title": "密码", + "type": "str", + "length": 255, + "cwidth": 18, + "uitype": "password", + "datatype": "str", + "label": "密码" + }, + { + "name": "email", + "title": "邮件地址", + "type": "str", + "length": 255, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "邮件地址" + }, + { + "name": "orgid", + "title": "所属机构", + "type": "str", + "length": 32, + "label": "所属机构", + "uitype": "code", + "valueField": "orgid", + "textField": "orgid_text", + "params": { + "dbname": "{{get_module_dbname('rbac')}}", + "table": "organization", + "tblvalue": "id", + "tbltext": "orgname", + "valueField": "orgid", + "textField": "orgid_text" + }, + "dataurl": "{{entire_url('/appbase/get_code.dspy')}}" + }, + { + "name": "nick_name", + "title": "显示名", + "type": "str", + "length": 255, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "显示名" + }, + { + "name": "address", + "title": "地址", + "type": "str", + "length": 255, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "地址" + }, + { + "name": "mobile", + "title": "手机", + "type": "str", + "length": 255, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "手机" + }, + { + "name": "user_status", + "title": "用户状态", + "type": "str", + "length": 1, + "default": "0", + "label": "用户状态", + "uitype": "code", + "valueField": "user_status", + "textField": "user_status_text", + "params": { + "dbname": "{{get_module_dbname('rbac')}}", + "table": "appcodes_kv", + "tblvalue": "k", + "tbltext": "v", + "valueField": "user_status", + "textField": "user_status_text", + "cond": "parentid='user_status'" + }, + "dataurl": "{{entire_url('/appbase/get_code.dspy')}}" + }, + { + "name": "created_at", + "title": "注册日期", + "type": "date", + "length": 0, + "uitype": "date", + "datatype": "date", + "label": "注册日期" + }, + { + "name": "last_login", + "title": "最后登录", + "type": "timestamp", + "nullable": true, + "length": 0, + "uitype": "str", + "datatype": "timestamp", + "label": "最后登录" + }, + { + "name": "login_fail_count", + "title": "连续失败次数", + "type": "short", + "default": "0", + "length": 0, + "uitype": "int", + "datatype": "short", + "label": "连续失败次数" + }, + { + "name": "last_login_fail", + "title": "最后登录失败时间", + "type": "timestamp", + "nullable": true, + "length": 0, + "uitype": "str", + "datatype": "timestamp", + "label": "最后登录失败时间" + }, + { + "name": "sync_from", + "title": "同步应用id", + "type": "str", + "length": 32, + "nullable": true, + "label": "同步应用id", + "uitype": "code", + "valueField": "sync_from", + "textField": "sync_from_text", + "params": { + "dbname": "{{get_module_dbname('rbac')}}", + "table": "downapp", + "tblvalue": "id", + "tbltext": "name", + "valueField": "sync_from", + "textField": "sync_from_text" + }, + "dataurl": "{{entire_url('/appbase/get_code.dspy')}}" + } +] + }, + + + + "page_rows":160, + "cache_limit":5 + } + + ,"binds":[ + { + "wid": "self", + "event": "enable_user", + "actiontype": "script", + "target": "self", + "script": "var tid=bricks.getWidgetById('users_tbl');var d=tid.select_row.user_data;fetch('/rbac/users/enable_user.dspy?id='+d.id,{method:'POST'}).then(function(r){return r.json()}).then(function(r){if(r.widgettype==='Message'){tid.render({})}else{bricks.show_error(r.options)}})" + }, + { + "wid": "self", + "event": "disable_user", + "actiontype": "script", + "target": "self", + "script": "var tid=bricks.getWidgetById('users_tbl');var d=tid.select_row.user_data;fetch('/rbac/users/disable_user.dspy?id='+d.id,{method:'POST'}).then(function(r){return r.json()}).then(function(r){if(r.widgettype==='Message'){tid.render({})}else{bricks.show_error(r.options)}})" + }, + { + "wid": "self", + "event": "userrole", + "actiontype": "urlwidget", + "target": "PopupWindow", + "popup_options": { + "title": "用户角色", + "icon": "{{entire_url('/appbase/get_icon.dspy')}}?id=userrole", + "resizable": true, + "height": "70%", + "width": "70%" + }, + "params_mapping": { + "mapping": { + "id": "userid", + "referer_widget": "referer_widget" + }, + "need_other": false + }, + "options": { + "method": "POST", + "params": {}, + "url": "{{entire_url('../userrole')}}" + } + } +] + +} \ No newline at end of file diff --git a/wwwroot/users/update_users.dspy b/wwwroot/users/update_users.dspy new file mode 100644 index 0000000..33b6936 --- /dev/null +++ b/wwwroot/users/update_users.dspy @@ -0,0 +1,73 @@ + +ns = params_kw.copy() +for k,v in ns.items(): + if v == 'NaN' or v == 'null': + ns[k] = None + + +userorgid = await get_userorgid() +if not userorgid: + return { + "widgettype":"Error", + "options":{ + "title":"Authorization Error", + "timeout":3, + "cwidth":16, + "cheight":9, + "message":"Please login" + } + } +ns['orgid'] = userorgid + + +if params_kw.get('password'): + ns['password'] = password_encode(params_kw.get('password')) + + +db = DBPools() +dbname = get_module_dbname('rbac') +async with db.sqlorContext(dbname) as sor: + + ns1 = { + + "orgid": userorgid, + + + "id": params_kw.id + } + recs = await sor.R('users', 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('users', 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