| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- """把 api 模块控制器里的 @RequestMapping(value=..., method={GET,POST}) 改成 @GetMapping / @PostMapping。
- HTTP 方法依据 uniapp 前端 api/*.js 的实际调用(request.get / request.post)逐条确定,
- admin / store 模块不动。
- """
- import re
- import sys
- from pathlib import Path
- sys.path.insert(0, str(Path(__file__).parent))
- from _root import ROOT # noqa: E402
- CTRL_DIR = ROOT / "yoshop-java" / "src/main/java/cn/yoshop/api/controller"
- # (完整路径 -> 方法),路径已含控制器类上的前缀
- METHODS = {
- # 收货地址
- "/api/address/list": "Get",
- "/api/address/defaultId": "Get",
- "/api/address/detail": "Get",
- "/api/address/add": "Post",
- "/api/address/edit": "Post",
- "/api/address/setDefault": "Post",
- "/api/address/remove": "Post",
- # 图形 / 短信验证码
- "/api/captcha/image": "Get",
- "/api/captcha/sendSmsCaptcha": "Post",
- # 购物车
- "/api/cart/list": "Get",
- "/api/cart/total": "Get",
- "/api/cart/add": "Post",
- "/api/cart/update": "Post",
- "/api/cart/clear": "Post",
- # 收银台
- "/api/cashier/orderInfo": "Get",
- "/api/cashier/orderPay": "Post",
- "/api/cashier/tradeQuery": "Get",
- # 结算台
- "/api/checkout/order": "Get",
- "/api/checkout/submit": "Post",
- # 内容
- "/api/category/list": "Get",
- "/api/article/list": "Get",
- "/api/article/detail": "Get",
- "/api/article.category/list": "Get",
- "/api/help/list": "Get",
- "/api/page/detail": "Get",
- # 商品
- "/api/goods/list": "Get",
- "/api/goods/detail": "Get",
- "/api/goods/basic": "Get",
- "/api/goods/specData": "Get",
- "/api/goods/skuInfo": "Get",
- "/api/goods.service/list": "Get",
- # 站点入口(纯文本兜底)
- "/api/index/index": "Get",
- # 营销
- "/api/comment/list": "Get",
- "/api/comment/total": "Get",
- "/api/comment/listRows": "Get",
- "/api/coupon/list": "Get",
- "/api/myCoupon/list": "Get",
- "/api/myCoupon/receive": "Post",
- "/api/express/list": "Get",
- # 订单
- "/api/order/list": "Get",
- "/api/order/detail": "Get",
- "/api/order/express": "Get",
- "/api/order/cancel": "Post",
- "/api/order/receipt": "Post",
- "/api/order/todoCounts": "Get",
- "/api/order.comment/list": "Get",
- "/api/order.comment/submit": "Post",
- # 登录
- "/api/passport/login": "Post",
- "/api/passport/loginMpWx": "Post",
- "/api/passport/loginMpWxMobile": "Post",
- "/api/passport/isPersonalMpweixin": "Post",
- # 充值
- "/api/recharge/center": "Get",
- "/api/recharge/submit": "Post",
- "/api/recharge/tradeQuery": "Get",
- "/api/recharge.order/list": "Get",
- # 售后
- "/api/refund/list": "Get",
- "/api/refund/goods": "Get",
- "/api/refund/apply": "Post",
- "/api/refund/detail": "Get",
- "/api/refund/delivery": "Post",
- # 地区
- "/api/region/all": "Get",
- "/api/region/tree": "Get",
- # 商城 / 设置
- "/api/store/data": "Get",
- "/api/setting/data": "Get",
- # 上传
- "/api/upload/image": "Post",
- # 用户
- "/api/user/info": "Get",
- "/api/user/assets": "Get",
- "/api/user/bindMobile": "Post",
- "/api/user/personal": "Post",
- "/api/balance.log/list": "Get",
- "/api/points.log/list": "Get",
- }
- ANN_RE = re.compile(r"@RequestMapping\((.*?)\)", re.S)
- VALUE_RE = re.compile(r'value\s*=\s*(\{[^}]*\}|"[^"]*")')
- PRODUCES_RE = re.compile(r'produces\s*=\s*("[^"]*"|[A-Za-z0-9_.]+)')
- def paths_of(value_expr):
- return re.findall(r'"([^"]*)"', value_expr)
- def norm_path(p):
- """把下划线写法归一成驼峰写法,用于查表。"""
- if "_" in p:
- head, *rest = p.split("_")
- # spec_data / sku_info / list_rows / todo_counts / set_default / default_id
- return head + "".join(w[:1].upper() + w[1:] for w in rest)
- return p
- def process(path: Path):
- src = path.read_text(encoding="utf-8")
- cls = re.search(r'^@RequestMapping\("([^"]+)"\)', src, re.M)
- prefix = cls.group(1) if cls else ""
- changed = 0
- def repl(m):
- nonlocal changed
- body = m.group(1)
- vm = VALUE_RE.search(body)
- if not vm:
- return m.group(0)
- value_expr = vm.group(1)
- paths = paths_of(value_expr)
- full = prefix + paths[0]
- key = norm_path(full)
- if key not in METHODS:
- raise SystemExit(f"未定义 HTTP 方法: {path.name} -> {full}")
- ann = METHODS[key]
- pm = PRODUCES_RE.search(body)
- parts = [f"value = {value_expr}"]
- if pm:
- parts.append(f"produces = {pm.group(1)}")
- changed += 1
- return f"@{ann}Mapping({', '.join(parts)})"
- new_src = ANN_RE.sub(repl, src)
- if not changed:
- return 0
- # 清理 / 补齐 import
- if "RequestMethod." not in new_src:
- new_src = new_src.replace(
- "import org.springframework.web.bind.annotation.RequestMethod;\n", "")
- for name in ("GetMapping", "PostMapping"):
- if f"@{name}(" in new_src and f"import org.springframework.web.bind.annotation.{name};" not in new_src:
- new_src = new_src.replace(
- "import org.springframework.web.bind.annotation.RequestMapping;",
- f"import org.springframework.web.bind.annotation.{name};\n"
- "import org.springframework.web.bind.annotation.RequestMapping;", 1)
- # import 块按字母排序
- lines = new_src.split("\n")
- idx = [i for i, ln in enumerate(lines) if ln.startswith("import ")]
- if idx:
- start, end = idx[0], idx[-1]
- block = lines[start:end + 1]
- if all(ln.startswith("import ") for ln in block):
- lines[start:end + 1] = sorted(set(block))
- new_src = "\n".join(lines)
- path.write_text(new_src, encoding="utf-8")
- return changed
- total = 0
- for f in sorted(CTRL_DIR.glob("*.java")):
- if f.name == "ApiNotifyController.java":
- continue
- n = process(f)
- if n:
- print(f"{f.name}: {n}")
- total += n
- print("合计:", total)
|