Compare commits
2 Commits
f62a33b2c0
...
e9c2525b18
| Author | SHA1 | Date | |
|---|---|---|---|
| e9c2525b18 | |||
| 021fc8d5e3 |
@@ -32,50 +32,36 @@ class ParameterChange:
|
||||
old_required: Optional[bool] = None
|
||||
detail: Optional[str] = None
|
||||
description: Optional[str] = None
|
||||
old_description: Optional[str] = None
|
||||
source: str = "query"
|
||||
|
||||
def _escape_cell(self, text: str) -> str:
|
||||
"""表格单元格转义。"""
|
||||
return text.replace("|", "\\|").replace("\n", " ")
|
||||
|
||||
def _change_label(self) -> str:
|
||||
"""变更列文案,对齐 model.md。"""
|
||||
if self.change_type == ChangeType.ADDED:
|
||||
if self.required is False:
|
||||
return "新增可选"
|
||||
return "新增必填"
|
||||
if self.change_type == ChangeType.REMOVED:
|
||||
return "删除"
|
||||
if self.change_type == ChangeType.RENAMED:
|
||||
return f"重命名 {self.old_name} → {self.param_name}"
|
||||
if self.change_type == ChangeType.MODIFIED:
|
||||
return self.detail or "修改"
|
||||
return "-"
|
||||
|
||||
def to_table_row(self) -> str:
|
||||
"""格式化为 model.md 参数变更表格行。"""
|
||||
desc = self._escape_cell(self.description or "-")
|
||||
change = self._escape_cell(self._change_label())
|
||||
return f"| `{self.param_name}` | {desc} | {change} |"
|
||||
|
||||
def to_markdown_line(self, *, plain: bool = False) -> str:
|
||||
"""
|
||||
格式化为企微 Markdown 行。
|
||||
plain=True 时用于新增接口,直接列出参数,不加「新增」前缀。
|
||||
"""
|
||||
req_optional = self.required is False
|
||||
req_required = self.required is True
|
||||
|
||||
if plain and self.change_type == ChangeType.ADDED:
|
||||
tag = (
|
||||
'<font color="warning">必填</font>'
|
||||
if req_required
|
||||
else '<font color="comment">可选</font>'
|
||||
)
|
||||
desc = f" <font color=\"comment\">{self.description}</font>" if self.description else ""
|
||||
return f'> `{self.param_type}` **{self.param_name}** · {tag}{desc}'
|
||||
|
||||
if self.change_type == ChangeType.REMOVED:
|
||||
return (
|
||||
f'<font color="warning">【删除】</font> '
|
||||
f'`{self.param_type}` ~~{self.param_name}~~'
|
||||
)
|
||||
if self.change_type == ChangeType.ADDED:
|
||||
tag = (
|
||||
'<font color="warning">必填</font>'
|
||||
if req_required
|
||||
else '<font color="comment">可选</font>'
|
||||
)
|
||||
desc = f" <font color=\"comment\">{self.description}</font>" if self.description else ""
|
||||
return (
|
||||
f'<font color="info">【新增】</font> '
|
||||
f'`{self.param_type}` **{self.param_name}** · {tag}{desc}'
|
||||
)
|
||||
if self.change_type == ChangeType.RENAMED:
|
||||
return (
|
||||
f'<font color="comment">【重命名】</font> '
|
||||
f'`{self.old_type}` {self.old_name} → '
|
||||
f'`{self.param_type}` **{self.param_name}**'
|
||||
)
|
||||
if self.change_type == ChangeType.MODIFIED:
|
||||
detail = f' · <font color="comment">{self.detail}</font>' if self.detail else ""
|
||||
return f'<font color="warning">【修改】</font> **{self.param_name}**{detail}'
|
||||
return f'- {self.param_name}'
|
||||
"""兼容旧调用,委托至表格行。"""
|
||||
return self.to_table_row()
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -116,6 +102,11 @@ def _param_key(p: ApiParameter) -> Tuple[str, str]:
|
||||
return (p.source, p.name)
|
||||
|
||||
|
||||
def _format_type_change(old_type: str, new_type: str) -> str:
|
||||
"""类型变更文案。"""
|
||||
return f"类型由{old_type}改为{new_type}"
|
||||
|
||||
|
||||
def compare_parameters(
|
||||
old_params: List[ApiParameter], new_params: List[ApiParameter]
|
||||
) -> List[ParameterChange]:
|
||||
@@ -146,9 +137,16 @@ def compare_parameters(
|
||||
new_p = new_map[key]
|
||||
detail_parts = []
|
||||
if old_p.type != new_p.type:
|
||||
detail_parts.append(f"类型 {old_p.type} -> {new_p.type}")
|
||||
detail_parts.append(_format_type_change(old_p.type, new_p.type))
|
||||
if old_p.required != new_p.required:
|
||||
detail_parts.append(f"必填 {old_p.required} -> {new_p.required}")
|
||||
req_label = lambda r: "必填" if r else "可选"
|
||||
detail_parts.append(
|
||||
f"必填性由{req_label(old_p.required)}改为{req_label(new_p.required)}"
|
||||
)
|
||||
if old_p.description != new_p.description:
|
||||
detail_parts.append(
|
||||
f"说明由{old_p.description or '-'}改为{new_p.description or '-'}"
|
||||
)
|
||||
if detail_parts:
|
||||
changes.append(
|
||||
ParameterChange(
|
||||
@@ -158,6 +156,9 @@ def compare_parameters(
|
||||
required=new_p.required,
|
||||
old_required=old_p.required,
|
||||
detail=", ".join(detail_parts),
|
||||
description=new_p.description,
|
||||
old_description=old_p.description,
|
||||
source=new_p.source,
|
||||
)
|
||||
)
|
||||
|
||||
@@ -186,6 +187,9 @@ def compare_parameters(
|
||||
old_name=r_param.name,
|
||||
old_type=r_param.type,
|
||||
required=a_param.required,
|
||||
description=a_param.description,
|
||||
old_description=r_param.description,
|
||||
source=a_param.source,
|
||||
)
|
||||
)
|
||||
matched_removed.add(r_key)
|
||||
@@ -200,6 +204,8 @@ def compare_parameters(
|
||||
change_type=ChangeType.REMOVED,
|
||||
param_name=param.name,
|
||||
param_type=param.type,
|
||||
description=param.description,
|
||||
source=param.source,
|
||||
)
|
||||
)
|
||||
|
||||
@@ -213,6 +219,7 @@ def compare_parameters(
|
||||
param_type=param.type,
|
||||
required=param.required,
|
||||
description=param.description,
|
||||
source=param.source,
|
||||
)
|
||||
)
|
||||
|
||||
@@ -370,6 +377,7 @@ def compare_endpoints(
|
||||
param_type=p.type,
|
||||
required=p.required,
|
||||
description=p.description,
|
||||
source=p.source,
|
||||
)
|
||||
for p in ep.parameters
|
||||
],
|
||||
|
||||
@@ -233,69 +233,64 @@ def _param_required(param: FormalParameter) -> bool:
|
||||
return not _has_ann(param, "Nullable")
|
||||
|
||||
|
||||
def _param_description(param: FormalParameter) -> Optional[str]:
|
||||
"""提取参数描述,优先 Swagger 注解,其次 @RequestParam 的 value。"""
|
||||
# 1. Swagger @ApiParam
|
||||
ann = _find_ann(param, "ApiParam")
|
||||
if ann:
|
||||
desc = _ann_string(ann, "value", "name")
|
||||
JAVADOC_PARAM_RE = re.compile(
|
||||
r"@param\s+(\w+)\s+(.*?)(?=\n\s*\*\s*@|\n\s*\*/|\Z)",
|
||||
re.DOTALL,
|
||||
)
|
||||
|
||||
|
||||
def _clean_javadoc_text(text: str) -> str:
|
||||
"""清理 JavaDoc 行前缀与多余空白。"""
|
||||
cleaned = re.sub(r"\s*\*\s?", " ", text)
|
||||
return re.sub(r"\s+", " ", cleaned).strip()
|
||||
|
||||
|
||||
def _parse_javadoc_params(javadoc: str) -> Dict[str, str]:
|
||||
"""从 JavaDoc 块解析 @param 名称 -> 说明。"""
|
||||
if not javadoc:
|
||||
return {}
|
||||
result: Dict[str, str] = {}
|
||||
for match in JAVADOC_PARAM_RE.finditer(javadoc):
|
||||
name = match.group(1)
|
||||
desc = _clean_javadoc_text(match.group(2))
|
||||
if desc:
|
||||
return desc
|
||||
result[name] = desc
|
||||
return result
|
||||
|
||||
# 2. Swagger @ApiImplicitParam(方法级注解,较少见,暂不实现)
|
||||
|
||||
# 3. Fallback: @RequestParam 的 value 作为描述提示
|
||||
ann = _find_ann(param, "RequestParam")
|
||||
if ann:
|
||||
val = _ann_string(ann, "value", "name")
|
||||
if val and val != param.name:
|
||||
return val
|
||||
def _extract_javadoc_before_line(source: str, target_line: int) -> str:
|
||||
"""
|
||||
提取目标行之前紧邻的 JavaDoc 块。
|
||||
target_line 为 1-indexed(与方法声明行号一致)。
|
||||
"""
|
||||
if not source or target_line <= 1:
|
||||
return ""
|
||||
lines = source.splitlines()
|
||||
idx = target_line - 2
|
||||
while idx >= 0 and not lines[idx].strip():
|
||||
idx -= 1
|
||||
while idx >= 0 and lines[idx].strip().startswith("@"):
|
||||
idx -= 1
|
||||
if idx < 0 or not lines[idx].strip().endswith("*/"):
|
||||
return ""
|
||||
end_idx = idx
|
||||
while idx >= 0 and not lines[idx].strip().startswith("/**"):
|
||||
idx -= 1
|
||||
if idx < 0:
|
||||
return ""
|
||||
return "\n".join(lines[idx : end_idx + 1])
|
||||
|
||||
|
||||
def _lookup_param_description(
|
||||
javadoc_params: Dict[str, str], param: FormalParameter, resolved_name: str
|
||||
) -> Optional[str]:
|
||||
"""按注解名或形参名匹配 JavaDoc @param 说明。"""
|
||||
for key in (resolved_name, param.name):
|
||||
if key and key in javadoc_params:
|
||||
return javadoc_params[key]
|
||||
return None
|
||||
|
||||
|
||||
def _parse_javadoc_params(source_code: str) -> Dict[str, Dict[str, str]]:
|
||||
"""
|
||||
使用正则从 Java 源代码中提取方法上的 Javadoc @param 描述。
|
||||
支持方法声明前存在注解(@GetMapping、@ApiOperation 等)的情况。
|
||||
|
||||
返回结构:
|
||||
{ method_name: { param_name: description } }
|
||||
"""
|
||||
javadoc_map: Dict[str, Dict[str, str]] = {}
|
||||
|
||||
# 改进正则:允许 Javadoc 后存在零或多个注解,再匹配方法声明
|
||||
pattern = re.compile(
|
||||
r'/\*\*(?P<javadoc>.*?)\*/\s*'
|
||||
r'(?:@\w+(?:\s*\([^)]*\))?\s*)*' # 跳过注解(支持 @GetMapping(...))
|
||||
r'(?:public|private|protected|static|final|\s)*'
|
||||
r'[\w<>\[\],\.\s]+?\s+(?P<method>\w+)\s*\(',
|
||||
re.DOTALL | re.MULTILINE
|
||||
)
|
||||
|
||||
for match in pattern.finditer(source_code):
|
||||
javadoc_block = match.group('javadoc')
|
||||
method_name = match.group('method')
|
||||
|
||||
param_descs: Dict[str, str] = {}
|
||||
# 提取 @param,支持多行描述(直到下一个 @ 或结束)
|
||||
param_pattern = re.compile(
|
||||
r'@param\s+(\w+)\s+((?:(?!\n\s*@).)+)',
|
||||
re.IGNORECASE | re.DOTALL
|
||||
)
|
||||
for p_match in param_pattern.finditer(javadoc_block):
|
||||
p_name = p_match.group(1)
|
||||
# 合并多行空白为单行
|
||||
p_desc = ' '.join(p_match.group(2).split())
|
||||
if p_desc:
|
||||
param_descs[p_name] = p_desc
|
||||
|
||||
if param_descs:
|
||||
javadoc_map[method_name] = param_descs
|
||||
|
||||
return javadoc_map
|
||||
|
||||
|
||||
class ControllerAstParser:
|
||||
"""
|
||||
基于 javalang 的 Controller 解析器。
|
||||
@@ -310,7 +305,7 @@ class ControllerAstParser:
|
||||
self.repo_root = repo_root
|
||||
self.source_dir = source_dir
|
||||
self._dto_cache: Dict[str, List[ApiParameter]] = {}
|
||||
self._javadoc_map: Dict[str, Dict[str, str]] = {} # method_name -> param_name -> description
|
||||
self._current_source = ""
|
||||
|
||||
def parse_file_content(self, source: str, repo_relative_path: str) -> List[ApiEndpoint]:
|
||||
"""
|
||||
@@ -321,15 +316,13 @@ class ControllerAstParser:
|
||||
:return: 端点列表
|
||||
"""
|
||||
endpoints: List[ApiEndpoint] = []
|
||||
self._current_source = source
|
||||
try:
|
||||
tree = javalang.parse.parse(source)
|
||||
except (javalang.parser.JavaSyntaxError, RecursionError) as exc:
|
||||
print(f"[警告] 解析失败 {repo_relative_path}: {exc}")
|
||||
return endpoints
|
||||
|
||||
# 解析当前文件的 Javadoc @param(用于参数描述回退)
|
||||
self._javadoc_map = _parse_javadoc_params(source)
|
||||
|
||||
for type_decl in tree.types or []:
|
||||
if not isinstance(type_decl, ClassDeclaration):
|
||||
continue
|
||||
@@ -367,9 +360,16 @@ class ControllerAstParser:
|
||||
continue
|
||||
|
||||
method_path = _ann_string(ann, "value", "path")
|
||||
javadoc_params: Dict[str, str] = {}
|
||||
if getattr(method, "position", None) and method.position:
|
||||
javadoc = _extract_javadoc_before_line(
|
||||
self._current_source, method.position.line
|
||||
)
|
||||
javadoc_params = _parse_javadoc_params(javadoc)
|
||||
|
||||
params = []
|
||||
for p in method.parameters or []:
|
||||
params.extend(self._extract_param(p, method_name=method.name))
|
||||
params.extend(self._extract_param(p, javadoc_params))
|
||||
|
||||
return ApiEndpoint(
|
||||
http_method=_http_method(ann_name, ann),
|
||||
@@ -381,10 +381,13 @@ class ControllerAstParser:
|
||||
)
|
||||
return None
|
||||
|
||||
def _extract_param(self, param: FormalParameter, method_name: Optional[str] = None) -> List[ApiParameter]:
|
||||
def _extract_param(
|
||||
self, param: FormalParameter, javadoc_params: Optional[Dict[str, str]] = None
|
||||
) -> List[ApiParameter]:
|
||||
"""提取方法参数,@RequestBody 展开 DTO 字段;忽略框架注入参数。"""
|
||||
type_name = _type_to_str(param.type)
|
||||
name = _param_name(param)
|
||||
javadoc_params = javadoc_params or {}
|
||||
|
||||
if _is_framework_param(type_name, name):
|
||||
return []
|
||||
@@ -392,19 +395,14 @@ class ControllerAstParser:
|
||||
if _has_ann(param, "RequestBody"):
|
||||
return self._expand_dto(type_name, "body")
|
||||
|
||||
desc = _param_description(param)
|
||||
|
||||
# Javadoc @param 回退(如果注解中没有描述)
|
||||
if not desc and method_name and method_name in self._javadoc_map:
|
||||
desc = self._javadoc_map[method_name].get(name)
|
||||
|
||||
description = _lookup_param_description(javadoc_params, param, name)
|
||||
return [
|
||||
ApiParameter(
|
||||
name=name,
|
||||
type=type_name,
|
||||
required=_param_required(param),
|
||||
source=_param_source(param),
|
||||
description=desc,
|
||||
description=description,
|
||||
)
|
||||
]
|
||||
|
||||
@@ -421,7 +419,8 @@ class ControllerAstParser:
|
||||
return result
|
||||
|
||||
try:
|
||||
tree = javalang.parse.parse(dto_file.read_text(encoding="utf-8", errors="ignore"))
|
||||
dto_source = dto_file.read_text(encoding="utf-8", errors="ignore")
|
||||
tree = javalang.parse.parse(dto_source)
|
||||
except (javalang.parser.JavaSyntaxError, OSError):
|
||||
result = [ApiParameter(name=simple, type=type_name, required=True, source=source)]
|
||||
self._dto_cache[simple] = result
|
||||
@@ -434,20 +433,22 @@ class ControllerAstParser:
|
||||
for field in type_decl.fields or []:
|
||||
if "static" in (field.modifiers or []):
|
||||
continue
|
||||
field_javadoc = ""
|
||||
if getattr(field, "position", None) and field.position:
|
||||
field_javadoc = _extract_javadoc_before_line(
|
||||
dto_source, field.position.line
|
||||
)
|
||||
field_desc = _clean_javadoc_text(
|
||||
field_javadoc.replace("/**", "").replace("*/", "").strip()
|
||||
) or None
|
||||
for decl in field.declarators:
|
||||
# 尝试提取 @ApiModelProperty 的描述
|
||||
desc = None
|
||||
api_model_ann = _find_ann(field, "ApiModelProperty")
|
||||
if api_model_ann:
|
||||
desc = _ann_string(api_model_ann, "value")
|
||||
|
||||
fields.append(
|
||||
ApiParameter(
|
||||
name=decl.name,
|
||||
type=_type_to_str(field.type),
|
||||
required=not _has_ann(field, "Nullable"),
|
||||
source=source,
|
||||
description=desc,
|
||||
description=field_desc,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -22,6 +22,46 @@ def truncate_text(text: str, max_length: int = MAX_MD_LENGTH) -> str:
|
||||
return text[:max_length] + "\n\n<font color=\"comment\">... 消息过长,已截断</font>"
|
||||
|
||||
|
||||
def _format_param_table(changes: List) -> List[str]:
|
||||
"""按 model.md 生成参数变更 Markdown 表格。"""
|
||||
if not changes:
|
||||
return ['<font color="comment">无</font>']
|
||||
lines = [
|
||||
"",
|
||||
"| 字段 | 说明 | 变更 |",
|
||||
"|------|------|------|",
|
||||
]
|
||||
for change in changes:
|
||||
lines.append(change.to_table_row())
|
||||
return lines
|
||||
|
||||
|
||||
def _format_param_details_section(report: EndpointChangeReport) -> List[str]:
|
||||
"""生成接口参数变动详情区块(对齐 model.md)。"""
|
||||
body_changes = [c for c in report.parameter_changes if c.source == "body"]
|
||||
regular_changes = [c for c in report.parameter_changes if c.source != "body"]
|
||||
lines = ["", "---", "", "## 接口参数变动详情", "", "---", ""]
|
||||
|
||||
if body_changes:
|
||||
lines.append("### 类对象变更")
|
||||
lines.append("")
|
||||
lines.append("- **参数变更列表:**")
|
||||
lines.extend(_format_param_table(body_changes))
|
||||
lines.append("")
|
||||
|
||||
if regular_changes:
|
||||
lines.append("### 普通参数变更(非对象字段)")
|
||||
lines.append("")
|
||||
lines.append("- **参数变更列表:**")
|
||||
lines.extend(_format_param_table(regular_changes))
|
||||
lines.append("")
|
||||
|
||||
if not body_changes and not regular_changes:
|
||||
lines.append('<font color="comment">无</font>')
|
||||
|
||||
return lines
|
||||
|
||||
|
||||
def _format_endpoint_block(report: EndpointChangeReport) -> str:
|
||||
"""
|
||||
格式化单个接口块,按模板匹配格式输出。
|
||||
@@ -41,21 +81,7 @@ def _format_endpoint_block(report: EndpointChangeReport) -> str:
|
||||
if report.is_removed_endpoint:
|
||||
return "\n".join(header + ["", f"<font color=\"warning\">**该接口已被移除**</font>"])
|
||||
|
||||
detail_lines = ["", "---------------------------------------", "", "## 【接口参数变动详情】", ""]
|
||||
|
||||
if report.is_new_endpoint:
|
||||
detail_lines.append("### <font color=\"info\">**新增接口参数**</font>")
|
||||
else:
|
||||
detail_lines.append("### <font color=\"warning\">**参数变更明细**</font>")
|
||||
|
||||
if report.parameter_changes:
|
||||
for change in report.parameter_changes:
|
||||
md = change.to_markdown_line(plain=report.is_new_endpoint)
|
||||
detail_lines.append(md)
|
||||
else:
|
||||
detail_lines.append('<font color="comment">无</font>')
|
||||
|
||||
return "\n".join(header + detail_lines)
|
||||
return "\n".join(header + _format_param_details_section(report))
|
||||
|
||||
|
||||
def build_markdown_notification(
|
||||
@@ -142,7 +168,7 @@ def build_markdown_notification(
|
||||
parts.append(path_md)
|
||||
parts.append("")
|
||||
|
||||
# 4. 普通参数变更(非路径变更)仍使用原有格式
|
||||
# 4. 普通参数变更(非路径变更)仍使用 model.md 格式
|
||||
if changed_reports:
|
||||
parts.append("# 【API参数变更通知】")
|
||||
parts.append(f"- **修改人:** {push_user}")
|
||||
@@ -291,6 +317,9 @@ def send_parameter_change_notification(
|
||||
push_time=push_time,
|
||||
file_name=report.source_file or report.controller_class,
|
||||
)
|
||||
if report.parameter_changes:
|
||||
param_section = "\n".join(_format_param_details_section(report)).strip()
|
||||
md = f"{md}\n\n{param_section}"
|
||||
if _post_wecom_markdown(webhook_url, md):
|
||||
sent += 1
|
||||
print(f"第 {sent} 条通知已发送到企业微信(新增接口)")
|
||||
@@ -325,10 +354,10 @@ def send_parameter_change_notification(
|
||||
|
||||
# ========== 3. 参数变更通知(独立分支) ==========
|
||||
if changed_reports:
|
||||
# 构建参数变更通知(只包含参数变更报告)
|
||||
# 构建参数变更通知(只包含参数变更报告,对齐 model.md)
|
||||
parts: List[str] = []
|
||||
parts.append("# 【API参数变更通知】")
|
||||
parts.append(f"- **修改人:** {push_user}")
|
||||
parts.append(f"- **修改人:** {push_user if push_user.startswith('@') else '@' + push_user}")
|
||||
parts.append(f"- **修改时间:** {push_time}")
|
||||
parts.append("")
|
||||
for report in changed_reports:
|
||||
|
||||
@@ -42,9 +42,8 @@ public class CultureClockInController {
|
||||
|
||||
/**
|
||||
* 打卡分享 - 获取随机图片
|
||||
*
|
||||
* @param lastCombo 上次组合
|
||||
* @param response HttpServletResponse
|
||||
* @param response HttpServletResponse
|
||||
*/
|
||||
@PostMapping(value = "/random-preview1")
|
||||
public void getRandomPicPreview(@RequestParam(value = "lastCombo1", required = false) String lastCombo1, HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
@@ -67,9 +66,8 @@ public class CultureClockInController {
|
||||
|
||||
/**
|
||||
* 打卡分享 - 获取随机图片[base64]
|
||||
*
|
||||
* @param lastCombo 上次组合
|
||||
* @param response HttpServletResponse
|
||||
* @param response HttpServletResponse
|
||||
*/
|
||||
// @GetMapping(value = "/random-preview/base641")
|
||||
@PutMapping(value = "/random-preview/base64")
|
||||
@@ -91,9 +89,8 @@ public class CultureClockInController {
|
||||
|
||||
/**
|
||||
* 打卡分享 - 获取随机图片[base64]
|
||||
*
|
||||
* @param lastCombo 上次组合
|
||||
* @param response HttpServletResponse
|
||||
* @param response HttpServletResponse
|
||||
*/
|
||||
@DeleteMapping(value = "/random-preview/delete")
|
||||
public ActionResult<Base64ImageVo> getRandomPicPreviewBase64(@RequestParam(value = "lastCombo", required = false) String lastCombo, HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
@@ -115,7 +112,6 @@ public class CultureClockInController {
|
||||
|
||||
/**
|
||||
* 打卡分享 - 打卡
|
||||
*
|
||||
* @param currentCombo 当前组合
|
||||
* @return jnpf.base.ActionResult<jnpf.model.culture.vo.CultureClockInVo>
|
||||
*/
|
||||
@@ -131,13 +127,12 @@ public class CultureClockInController {
|
||||
|
||||
/**
|
||||
* 打卡动态 - 打卡记录列表
|
||||
*
|
||||
* @param cursorDate 游标日期(yyyy-MM-dd)[首次不传]
|
||||
* @param limitNum 返回有数据的天数
|
||||
* @param limitNum 返回有数据的天数
|
||||
* @return jnpf.base.ActionResult<jnpf.model.culture.vo.RecordListVo>
|
||||
*/
|
||||
@GetMapping(value = "/dynamic1")
|
||||
public ActionResult<RecordListVo> getRecordList(@RequestParam(value = "cursorDate1", required = false) String cursorDate,
|
||||
public ActionResult<RecordListVo> getRecordList(@RequestParam(value = "cursorDate1", required = false) Boolean cursorDate,
|
||||
@RequestParam(value = "limitNum", required = false, defaultValue = "10") Integer limitNum) {
|
||||
|
||||
limitNum = Math.max(10, Math.min(limitNum, 30));
|
||||
@@ -147,7 +142,6 @@ public class CultureClockInController {
|
||||
|
||||
/**
|
||||
* 打卡日历
|
||||
*
|
||||
* @param year 年
|
||||
* @return jnpf.base.ActionResult<jnpf.model.culture.vo.YearDataVo>
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user