# -*- coding: utf-8 -*- """MISSING 4: programmatically write the 4 .bru files into docs repo. r-list content is copied from the already-captured tmp/m4-r-list.md; region live examples are re-dumped from m4-region-live.json (real data).""" import io import json import os import shutil import sys sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8") DOCS = r"D:\code\crm-api-docs" TMP = r"d:\code\crm-backend-matt\tmp" LIVE = json.load(open(r"d:\code\crm-backend-matt\.scratch\auth-perms\m4-region-live.json", encoding="utf-8")) D_REGION = "\u516c\u5171\u4f9d\u8d56-\u884c\u653f\u533a\u5212" # 公共依赖-行政区划 D_SYS = "\u7cfb\u7edf\u7ba1\u7406" # 系统管理 D_OPS = "\u8fd0\u7ef4" # 运维 F_LIST = "\u6309\u4e0a\u7ea7\u67e5\u5b50\u533a\u5212.bru" # 按上级查子区划.bru F_LEVEL = "\u6309\u5c42\u7ea7\u67e5\u533a\u5212.bru" # 按层级查区划.bru F_DT = "\u9489\u9489\u7ec4\u7ec7\u540c\u6b65.bru" # 钉钉组织同步.bru F_AR = "\u7ba1\u7406\u5458\u89d2\u8272\u914d\u7f6e.bru" # 管理员角色配置.bru def write_bru(rel_parts, content): p = os.path.join(DOCS, *rel_parts) with open(p, "w", encoding="utf-8", newline="") as f: f.write(content) print("WROTE", os.path.relpath(p, DOCS), len(content.encode("utf-8")), "bytes") def rows_json(rows): return json.dumps(rows, ensure_ascii=False, indent=2) # ── 1) r-list: copy captured md verbatim ── src = open(os.path.join(TMP, "m4-r-list.md"), encoding="utf-8").read() assert src.startswith("meta {") and src.rstrip().endswith("}"), "r-list payload broken" write_bru([D_REGION, F_LIST], src) # ── 2) r-level: rebuild from live data ── prov = [LIVE["level1"]["data"][0], LIVE["level1"]["data"][1]] # 北京市 / 天津市 lvl1 = "".join(" " + ln + "\n" for ln in rows_json(prov).splitlines()).rstrip("\n") LEVEL = """meta { name: 按层级查区划 type: http seq: 2 tags: [ generated ] } get { url: {{baseUrl}}/api/rule/region/level?level=1 body: none auth: inherit } params:query { level: 1 } docs { # 按层级查区划 `GET /api/rule/region/level` 按层级整层拉取行政区划(公共依赖,登录即可访问):1=省(34 行)2=市(342 行)3=区。level 必填。 ## 请求参数 | 参数 | 类型 | 必填 | 默认 | 说明 | | --- | --- | --- | --- | --- | | level | int | 是 | - | 层级:1=省 2=市 3=区 | ## 请求示例 请求头:Authorization: Bearer {{token}} GET /api/rule/region/level?level=1 ## 响应 data 结构 data 为 SysRegionDTO 数组(扁平列表,非树形),字段同「按上级查子区划」: | 字段 | 类型 | 说明 | | --- | --- | --- | | [].id | string | 区划 ID(雪花,序列化为 string) | | [].createTime | string | 创建时间 | | [].updateTime | string | 更新时间 | | [].code | string | 行政区划代码(6 位国标,如 110000) | | [].name | string | 区划名称 | | [].parentId | string | 上级区划 ID,省级为 null | | [].level | int | 层级:1=省 2=市 3=区 | ## 响应示例 // 真实返回摘录(level=1,共 34 行,此处截前 2 行) ```json { "code": 0, "success": true, "message": "success", "data": [ {LVL1} ] } ``` } """.replace("{LVL1}", lvl1) write_bru([D_REGION, F_LEVEL], LEVEL) # ── 3) dingtalk sync ── DT = """meta { name: 钉钉组织同步 type: http seq: 1 tags: [ generated ] } post { url: {{baseUrl}}/api/system/sync/dingtalk body: none auth: inherit } docs { # 钉钉组织同步 `POST /api/system/sync/dingtalk` 全量同步钉钉部门树与用户(幂等,可重跑)。 > 需 ADMIN 角色。同步阻塞执行,组织规模大时耗时较长。 > 无请求参数,同步范围与对账口径由服务端配置决定。 ## 请求参数 无 ## 请求示例 请求头:Authorization: Bearer {{token}} POST /api/system/sync/dingtalk ## 响应 data 结构 data 为 DtSyncResultDTO(同步对账结果): | 字段 | 类型 | 说明 | | --- | --- | --- | | deptTotal | int | 钉钉侧部门总数 | | deptInserted | int | 本次新增的部门数 | | deptUpdated | int | 本次更新的部门数(改名/移动/排序变化) | | userTotal | int | 钉钉侧用户总数(去重后) | | userInserted | int | 本次新增的用户数 | | userUpdated | int | 本次更新的用户数 | | leaderAssigned | int | 反写部门负责人(leaderUserId)的部门数 | ## 响应示例 // 示例数据,字段结构以上表为准,非真实返回 ```json { "code": 0, "success": true, "message": "success", "data": { "deptTotal": 42, "deptInserted": 0, "deptUpdated": 3, "userTotal": 120, "userInserted": 2, "userUpdated": 5, "leaderAssigned": 18 } } ``` } """ write_bru([D_SYS, D_OPS, F_DT], DT) # ── 4) admin-role ── AR = """meta { name: 管理员角色配置 type: http seq: 2 tags: [ generated ] } post { url: {{baseUrl}}/api/system/users/admin-role body: formUrlEncoded auth: inherit } body:form-urlencoded { userId: 739564171091247104 roleCodes: ROLE_ADMIN grant: true } docs { # 管理员角色配置 `POST /api/system/users/admin-role` 给指定用户增量授予/回收管理员类角色,不影响该用户的其他角色。 > 需 ADMIN 角色。roleCodes 缺省 ROLE_ADMIN;grant 缺省 true(授予)。 ## 请求参数 | 参数 | 类型 | 必填 | 默认 | 说明 | | --- | --- | --- | --- | --- | | userId | string | 是 | - | 目标用户 ID(雪花按字符串收发) | | roleCodes | string | 否 | ROLE_ADMIN | 管理员类角色编码,逗号分隔 | | grant | boolean | 否 | true | true=授予,false=回收 | ## 请求示例 请求头:Authorization: Bearer {{token}} Content-Type: application/x-www-form-urlencoded POST /api/system/users/admin-role userId=739564171091247104&roleCodes=ROLE_ADMIN&grant=true ## 响应 data 结构 null ## 响应示例 // 示例数据,非真实返回 ```json { "code": 0, "success": true, "message": "success", "data": null } ``` } """ write_bru([D_SYS, D_OPS, F_AR], AR) # ── sanity: no placeholder left anywhere ── for parts in [[D_REGION, F_LIST], [D_REGION, F_LEVEL], [D_SYS, D_OPS, F_DT], [D_SYS, D_OPS, F_AR]]: c = open(os.path.join(DOCS, *parts), encoding="utf-8").read() assert "BRU_PLACEHOLDER_M4" not in c and c.startswith("meta {"), parts print("DONE-ALL")