Compare commits

...

19 Commits

Author SHA1 Message Date
4ebb71f7a0 测试:普通参数--新增&修改&删除
All checks were successful
API接口参数变更检测 / api-param-check (push) Successful in 24s
2026-06-05 17:24:59 +08:00
88aff91e5d 测试:普通参数--删除
All checks were successful
API接口参数变更检测 / api-param-check (push) Successful in 19s
2026-06-05 17:22:54 +08:00
d0aeefa1e7 测试:普通参数--新增
All checks were successful
API接口参数变更检测 / api-param-check (push) Successful in 19s
2026-06-05 17:21:19 +08:00
eec5608cce 测试:参数修改
All checks were successful
API接口参数变更检测 / api-param-check (push) Successful in 21s
2026-06-05 17:18:27 +08:00
380bc41fc4 测试:路径修改
All checks were successful
API接口参数变更检测 / api-param-check (push) Successful in 21s
2026-06-05 17:16:56 +08:00
eb4856ab56 测试:新增接口
All checks were successful
API接口参数变更检测 / api-param-check (push) Successful in 21s
2026-06-05 16:57:00 +08:00
326419bc53 测试:删除接口
All checks were successful
API接口参数变更检测 / api-param-check (push) Successful in 20s
2026-06-05 16:54:04 +08:00
a128241ccc 测试:请求方式变更
All checks were successful
API接口参数变更检测 / api-param-check (push) Successful in 20s
2026-06-05 16:52:20 +08:00
3e6fb3012b 接口类对象解析
All checks were successful
API接口参数变更检测 / api-param-check (push) Successful in 20s
2026-06-05 16:44:10 +08:00
2d1292262a 接口类对象解析
Some checks failed
API接口参数变更检测 / api-param-check (push) Has been cancelled
2026-06-05 16:43:57 +08:00
51145e7c78 接口类对象解析
Some checks failed
API接口参数变更检测 / api-param-check (push) Has been cancelled
2026-06-05 16:41:16 +08:00
90b0045659 接口类对象解析
All checks were successful
API接口参数变更检测 / api-param-check (push) Successful in 20s
2026-06-05 16:39:16 +08:00
a1c28570d4 接口类对象解析 2026-06-05 16:39:02 +08:00
ba3f1c6507 接口类对象解析
All checks were successful
API接口参数变更检测 / api-param-check (push) Successful in 19s
2026-06-05 16:36:16 +08:00
03fb9766a6 接口类对象解析 2026-06-05 16:35:51 +08:00
3cba3bb74e commit
Some checks failed
API接口参数变更检测 / api-param-check (push) Has been cancelled
2026-06-05 16:18:40 +08:00
1ca34c6bb2 字段说明测试--改动两个
All checks were successful
API接口参数变更检测 / api-param-check (push) Successful in 17s
2026-06-05 16:02:19 +08:00
026a490125 字段说明测试
All checks were successful
API接口参数变更检测 / api-param-check (push) Successful in 17s
2026-06-05 16:00:12 +08:00
c46cb06391 字段说明测试 2026-06-05 16:00:07 +08:00
4401 changed files with 450287 additions and 189 deletions

View File

@@ -34,34 +34,69 @@ class ParameterChange:
description: Optional[str] = None description: Optional[str] = None
old_description: Optional[str] = None old_description: Optional[str] = None
source: str = "query" source: str = "query"
parent_dto: Optional[str] = None
body_param_name: Optional[str] = None
def _escape_cell(self, text: str) -> str: def _change_tag(self) -> str:
"""表格单元格转义""" """变更类型标签(企微颜色)"""
return text.replace("|", "\\|").replace("\n", " ") tags = {
ChangeType.ADDED: '<font color="info">**新增**</font>',
ChangeType.REMOVED: '<font color="warning">**删除**</font>',
ChangeType.RENAMED: '<font color="comment">**重命名**</font>',
ChangeType.MODIFIED: '<font color="warning">**修改**</font>',
}
return tags.get(self.change_type, "")
def _change_label(self) -> str: def _required_tag(self) -> str:
"""变更列文案,对齐 model.md""" """必填/可选标签"""
if self.change_type == ChangeType.ADDED: if self.required is True:
return '<font color="warning">必填</font>'
if self.required is False: if self.required is False:
return "新增可选" return '<font color="comment">可选</font>'
return "新增必填" return ""
if self.change_type == ChangeType.REMOVED:
return "删除" def to_markdown_block(self, index: int = 1) -> str:
"""格式化为企微友好的参数变更卡片(列表式,非表格)。"""
lines: List[str] = []
desc = self.description or self.old_description
if self.change_type == ChangeType.RENAMED: if self.change_type == ChangeType.RENAMED:
return f"重命名 {self.old_name} {self.param_name}" lines.append(f"**{index}. `{self.param_name}`** {self._change_tag()}")
if self.change_type == ChangeType.MODIFIED: lines.append(f"> `{self.old_name}` → `{self.param_name}`")
return self.detail or "修改" if desc:
return "-" lines.append(f"> 说明:{desc}")
return "\n".join(lines)
if self.change_type == ChangeType.ADDED:
type_part = f" · `{self.param_type}`" if self.param_type else ""
req_part = f" · {self._required_tag()}" if self._required_tag() else ""
lines.append(
f"**{index}. `{self.param_name}`**{type_part}{req_part} {self._change_tag()}"
)
if desc:
lines.append(f"> 说明:{desc}")
return "\n".join(lines)
if self.change_type == ChangeType.REMOVED:
type_part = f" · `{self.param_type}`" if self.param_type else ""
lines.append(
f"**{index}. `{self.param_name}`**{type_part} {self._change_tag()}"
)
if desc:
lines.append(f"> 说明:{desc}")
return "\n".join(lines)
# MODIFIED
lines.append(f"**{index}. `{self.param_name}`** {self._change_tag()}")
if desc:
lines.append(f"> 说明:{desc}")
if self.detail:
lines.append(f"> 变更:{self.detail}")
return "\n".join(lines)
def to_table_row(self) -> str: def to_table_row(self) -> str:
"""格式化为 model.md 参数变更表格行""" """兼容旧调用,委托至卡片块"""
desc = self._escape_cell(self.description or "-") return self.to_markdown_block(1)
change = self._escape_cell(self._change_label())
return f"| `{self.param_name}` | {desc} | {change} |"
def to_markdown_line(self, *, plain: bool = False) -> str:
"""兼容旧调用,委托至表格行。"""
return self.to_table_row()
@dataclass @dataclass
@@ -159,6 +194,8 @@ def compare_parameters(
description=new_p.description, description=new_p.description,
old_description=old_p.description, old_description=old_p.description,
source=new_p.source, source=new_p.source,
parent_dto=new_p.parent_dto,
body_param_name=new_p.body_param_name,
) )
) )
@@ -190,6 +227,8 @@ def compare_parameters(
description=a_param.description, description=a_param.description,
old_description=r_param.description, old_description=r_param.description,
source=a_param.source, source=a_param.source,
parent_dto=a_param.parent_dto,
body_param_name=a_param.body_param_name,
) )
) )
matched_removed.add(r_key) matched_removed.add(r_key)
@@ -206,6 +245,8 @@ def compare_parameters(
param_type=param.type, param_type=param.type,
description=param.description, description=param.description,
source=param.source, source=param.source,
parent_dto=param.parent_dto,
body_param_name=param.body_param_name,
) )
) )
@@ -220,6 +261,8 @@ def compare_parameters(
required=param.required, required=param.required,
description=param.description, description=param.description,
source=param.source, source=param.source,
parent_dto=param.parent_dto,
body_param_name=param.body_param_name,
) )
) )
@@ -378,6 +421,8 @@ def compare_endpoints(
required=p.required, required=p.required,
description=p.description, description=p.description,
source=p.source, source=p.source,
parent_dto=p.parent_dto,
body_param_name=p.body_param_name,
) )
for p in ep.parameters for p in ep.parameters
], ],

View File

@@ -23,6 +23,8 @@ from javalang.tree import (
from models import ApiEndpoint, ApiParameter from models import ApiEndpoint, ApiParameter
# javax.validation 必填注解
REQUIRED_FIELD_ANNS = {"NotNull", "NotEmpty", "NotBlank"}
MAPPING_ANNS = {"GetMapping", "PostMapping", "PutMapping", "DeleteMapping", "PatchMapping", "RequestMapping"} MAPPING_ANNS = {"GetMapping", "PostMapping", "PutMapping", "DeleteMapping", "PatchMapping", "RequestMapping"}
CONTROLLER_ANNS = {"RestController", "Controller"} CONTROLLER_ANNS = {"RestController", "Controller"}
@@ -281,6 +283,16 @@ def _extract_javadoc_before_line(source: str, target_line: int) -> str:
return "\n".join(lines[idx : end_idx + 1]) return "\n".join(lines[idx : end_idx + 1])
def _field_required(field: FieldDeclaration) -> bool:
"""DTO 字段是否必填(@NotNull / @NotEmpty / @NotBlank"""
if _has_ann(field, "Nullable"):
return False
for ann in field.annotations or []:
if _ann_simple_name(ann) in REQUIRED_FIELD_ANNS:
return True
return False
def _lookup_param_description( def _lookup_param_description(
javadoc_params: Dict[str, str], param: FormalParameter, resolved_name: str javadoc_params: Dict[str, str], param: FormalParameter, resolved_name: str
) -> Optional[str]: ) -> Optional[str]:
@@ -297,13 +309,13 @@ class ControllerAstParser:
只解析传入的文件不扫描整个目录CI 更快)。 只解析传入的文件不扫描整个目录CI 更快)。
""" """
def __init__(self, repo_root: Path, source_dir: Path): def __init__(self, repo_root: Path, source_dirs: List[Path]):
""" """
:param repo_root: 仓库根目录 :param repo_root: 仓库根目录
:param source_dir: Java 源码根目录repo_root 下的相对路径对应的绝对路径 :param source_dirs: Java 源码根目录列表(用于查找 DTO 等
""" """
self.repo_root = repo_root self.repo_root = repo_root
self.source_dir = source_dir self.source_dirs = source_dirs
self._dto_cache: Dict[str, List[ApiParameter]] = {} self._dto_cache: Dict[str, List[ApiParameter]] = {}
self._current_source = "" self._current_source = ""
@@ -393,7 +405,13 @@ class ControllerAstParser:
return [] return []
if _has_ann(param, "RequestBody"): if _has_ann(param, "RequestBody"):
return self._expand_dto(type_name, "body") body_desc = _lookup_param_description(javadoc_params, param, name)
return self._expand_dto(
type_name,
"body",
body_param_name=param.name,
body_param_desc=body_desc,
)
description = _lookup_param_description(javadoc_params, param, name) description = _lookup_param_description(javadoc_params, param, name)
return [ return [
@@ -406,24 +424,51 @@ class ControllerAstParser:
) )
] ]
def _expand_dto(self, type_name: str, source: str) -> List[ApiParameter]: def _expand_dto(
"""展开 @RequestBody DTO 字段。""" self,
type_name: str,
source: str,
body_param_name: str = "",
body_param_desc: Optional[str] = None,
) -> List[ApiParameter]:
"""展开 @RequestBody DTO 一级字段。"""
simple = type_name.split(".")[-1].replace(">", "").replace("<", "").strip() simple = type_name.split(".")[-1].replace(">", "").replace("<", "").strip()
if simple in self._dto_cache: cache_key = f"{simple}:{body_param_name}"
return self._dto_cache[simple] if cache_key in self._dto_cache:
return self._dto_cache[cache_key]
dto_file = self._find_dto_file(simple) dto_file = self._find_dto_file(simple)
if not dto_file: if not dto_file:
result = [ApiParameter(name=simple, type=type_name, required=True, source=source)] result = [
self._dto_cache[simple] = result ApiParameter(
name=simple,
type=type_name,
required=True,
source=source,
description=body_param_desc,
parent_dto=simple,
body_param_name=body_param_name or None,
)
]
self._dto_cache[cache_key] = result
return result return result
try: try:
dto_source = 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) tree = javalang.parse.parse(dto_source)
except (javalang.parser.JavaSyntaxError, OSError): except (javalang.parser.JavaSyntaxError, OSError):
result = [ApiParameter(name=simple, type=type_name, required=True, source=source)] result = [
self._dto_cache[simple] = result ApiParameter(
name=simple,
type=type_name,
required=True,
source=source,
description=body_param_desc,
parent_dto=simple,
body_param_name=body_param_name or None,
)
]
self._dto_cache[cache_key] = result
return result return result
fields: List[ApiParameter] = [] fields: List[ApiParameter] = []
@@ -446,31 +491,47 @@ class ControllerAstParser:
ApiParameter( ApiParameter(
name=decl.name, name=decl.name,
type=_type_to_str(field.type), type=_type_to_str(field.type),
required=not _has_ann(field, "Nullable"), required=_field_required(field),
source=source, source=source,
description=field_desc, description=field_desc,
parent_dto=simple,
body_param_name=body_param_name or None,
) )
) )
if not fields: if not fields:
fields = [ApiParameter(name=simple, type=type_name, required=True, source=source)] fields = [
ApiParameter(
name=simple,
type=type_name,
required=True,
source=source,
description=body_param_desc,
parent_dto=simple,
body_param_name=body_param_name or None,
)
]
self._dto_cache[simple] = fields self._dto_cache[cache_key] = fields
return fields return fields
def _find_dto_file(self, simple_name: str) -> Optional[Path]: def _find_dto_file(self, simple_name: str) -> Optional[Path]:
"""在源码目录中查找 DTO 文件。""" """配置的源码目录及仓库内 src/main/java 中查找 DTO 文件。"""
if not self.source_dir.exists():
return None
target = f"{simple_name}.java" target = f"{simple_name}.java"
for path in self.source_dir.rglob(target): for source_dir in self.source_dirs:
if source_dir.exists():
for path in source_dir.rglob(target):
return path
if self.repo_root.exists():
for path in self.repo_root.rglob(target):
if "src/main/java" in path.as_posix():
return path return path
return None return None
def parse_controller_files( def parse_controller_files(
repo_root: Path, repo_root: Path,
source_subdir: str, source_subdirs: List[str],
file_paths: List[str], file_paths: List[str],
file_contents: Dict[str, str], file_contents: Dict[str, str],
) -> List[ApiEndpoint]: ) -> List[ApiEndpoint]:
@@ -478,13 +539,13 @@ def parse_controller_files(
批量解析指定 Controller 文件(仅解析传入的文件,不全量扫描)。 批量解析指定 Controller 文件(仅解析传入的文件,不全量扫描)。
:param repo_root: 仓库根目录 :param repo_root: 仓库根目录
:param source_subdir: 源码子目录(相对仓库根) :param source_subdirs: 源码子目录列表(相对仓库根)
:param file_paths: 要解析的文件路径列表(相对仓库根) :param file_paths: 要解析的文件路径列表(相对仓库根)
:param file_contents: {文件路径: 源码内容} :param file_contents: {文件路径: 源码内容}
:return: 所有端点 :return: 所有端点
""" """
source_dir = (repo_root / source_subdir).resolve() source_dirs = [(repo_root / sub).resolve() for sub in source_subdirs]
parser = ControllerAstParser(repo_root, source_dir) parser = ControllerAstParser(repo_root, source_dirs)
endpoints: List[ApiEndpoint] = [] endpoints: List[ApiEndpoint] = []
for path in file_paths: for path in file_paths:

View File

@@ -25,7 +25,7 @@ def filter_endpoints_by_files(
def parse_endpoints_from_files( def parse_endpoints_from_files(
repo_root: Path, repo_root: Path,
source_subdir: str, source_subdirs: List[str],
file_paths: List[str], file_paths: List[str],
file_contents: Dict[str, str], file_contents: Dict[str, str],
) -> List[ApiEndpoint]: ) -> List[ApiEndpoint]:
@@ -33,11 +33,11 @@ def parse_endpoints_from_files(
解析指定 Controller 文件,提取接口参数(仅解析传入文件,不全量扫描)。 解析指定 Controller 文件,提取接口参数(仅解析传入文件,不全量扫描)。
:param repo_root: 仓库根 :param repo_root: 仓库根
:param source_subdir: 源码目录(相对仓库根) :param source_subdirs: 源码目录列表(相对仓库根)
:param file_paths: 文件路径列表 :param file_paths: 文件路径列表
:param file_contents: 路径 -> 源码内容 :param file_contents: 路径 -> 源码内容
:return: ApiEndpoint 列表 :return: ApiEndpoint 列表
""" """
from controller_ast_parser import parse_controller_files from controller_ast_parser import parse_controller_files
return parse_controller_files(repo_root, source_subdir, file_paths, file_contents) return parse_controller_files(repo_root, source_subdirs, file_paths, file_contents)

View File

@@ -42,6 +42,14 @@ def load_config(config_path: Path) -> dict:
return yaml.safe_load(f) or {} return yaml.safe_load(f) or {}
def resolve_source_subdirs(config: dict) -> list:
"""从配置解析 Java 源码目录列表(支持 source_dirs 多模块)。"""
dirs = config.get("source_dirs")
if dirs:
return [str(d) for d in dirs]
return [config.get("source_dir", "src/main/java")]
def _read_file_safe(path: Path) -> str: def _read_file_safe(path: Path) -> str:
"""读取文件内容。""" """读取文件内容。"""
try: try:
@@ -73,7 +81,7 @@ def _load_version_contents(
def parse_changed_endpoints( def parse_changed_endpoints(
repo_root: Path, repo_root: Path,
source_subdir: str, source_subdirs: list,
changed_files: list, changed_files: list,
old_sha: str, old_sha: str,
label: str, label: str,
@@ -86,7 +94,7 @@ def parse_changed_endpoints(
print(f"[AST] 解析 {label} 版本 {len(contents)} 个 Controller 文件") print(f"[AST] 解析 {label} 版本 {len(contents)} 个 Controller 文件")
endpoints = parse_endpoints_from_files( endpoints = parse_endpoints_from_files(
repo_root, source_subdir, changed_files, contents repo_root, source_subdirs, changed_files, contents
) )
print(f"[AST] {label} 版本共 {len(endpoints)} 个接口") print(f"[AST] {label} 版本共 {len(endpoints)} 个接口")
return endpoints_to_map(endpoints) return endpoints_to_map(endpoints)
@@ -111,7 +119,11 @@ def main() -> int:
config_path = repo_root / config_path config_path = repo_root / config_path
config = load_config(config_path) config = load_config(config_path)
source_subdir = config.get("source_dir", "src/main/java") if not config.get("check", {}).get("enabled", True):
print("[检查] API 变动检查已关闭check.enabled=false跳过。")
return 0
source_subdirs = resolve_source_subdirs(config)
commit_info = get_current_commit() commit_info = get_current_commit()
push_user = args.push_user or commit_info.author push_user = args.push_user or commit_info.author
@@ -121,6 +133,8 @@ def main() -> int:
print("=" * 40) print("=" * 40)
print(f"推送人: {push_user}") print(f"推送人: {push_user}")
print(f"推送时间: {push_time}") print(f"推送时间: {push_time}")
print(f"API 变动检查: {config.get('check', {}).get('enabled', True)}")
print(f"源码目录: {', '.join(source_subdirs)}")
print(f"LLM 审核: {config.get('llm', {}).get('enabled', True)}") print(f"LLM 审核: {config.get('llm', {}).get('enabled', True)}")
print(f"记录日志: {config.get('log', {}).get('enabled', False)}") print(f"记录日志: {config.get('log', {}).get('enabled', False)}")
print("=" * 40) print("=" * 40)
@@ -142,10 +156,10 @@ def main() -> int:
git_diff = get_controller_files_diff(prev_sha, commit_info.sha, changed_files) git_diff = get_controller_files_diff(prev_sha, commit_info.sha, changed_files)
new_map = parse_changed_endpoints( new_map = parse_changed_endpoints(
repo_root, source_subdir, changed_files, prev_sha, "new" repo_root, source_subdirs, changed_files, prev_sha, "new"
) )
old_map = parse_changed_endpoints( old_map = parse_changed_endpoints(
repo_root, source_subdir, changed_files, prev_sha, "old" repo_root, source_subdirs, changed_files, prev_sha, "old"
) )
new_filtered = endpoints_to_map( new_filtered = endpoints_to_map(

View File

@@ -15,6 +15,8 @@ class ApiParameter:
required: bool = True required: bool = True
source: str = "query" source: str = "query"
description: Optional[str] = None description: Optional[str] = None
parent_dto: Optional[str] = None
body_param_name: Optional[str] = None
@dataclass @dataclass

View File

@@ -5,11 +5,12 @@
import json import json
import re import re
from typing import List, Optional from collections import OrderedDict
from typing import List, Optional, Tuple
import requests import requests
from comparator import EndpointChangeReport from comparator import EndpointChangeReport, ParameterChange
# 企微 Markdown 单条上限 4096 字符,留余量 # 企微 Markdown 单条上限 4096 字符,留余量
MAX_MD_LENGTH = 3800 MAX_MD_LENGTH = 3800
@@ -22,38 +23,78 @@ def truncate_text(text: str, max_length: int = MAX_MD_LENGTH) -> str:
return text[:max_length] + "\n\n<font color=\"comment\">... 消息过长,已截断</font>" return text[:max_length] + "\n\n<font color=\"comment\">... 消息过长,已截断</font>"
def _format_param_table(changes: List) -> List[str]: def _format_param_change_list(changes: List[ParameterChange]) -> List[str]:
"""按 model.md 生成参数变更 Markdown 表格""" """生成企微友好的普通参数变更列表(卡片式)"""
if not changes: if not changes:
return ['<font color="comment">无</font>'] return ['<font color="comment">无</font>']
lines = [ lines = ["", f"共 **{len(changes)}** 项变更", ""]
"", for i, change in enumerate(changes, 1):
"| 字段 | 说明 | 变更 |", lines.append(change.to_markdown_block(i))
"|------|------|------|", if i < len(changes):
] lines.append("")
return lines
def _body_dto_group_key(change: ParameterChange) -> Tuple[str, str]:
"""类对象变更分组键:(body 参数名, DTO 类名)。"""
return (change.body_param_name or "body", change.parent_dto or "")
def _format_body_field_line(change: ParameterChange, *, is_last: bool) -> List[str]:
"""格式化 DTO 一级字段变更行。"""
branch = "└─" if is_last else "├─"
desc = change.description or change.old_description
type_part = f" · `{change.param_type}`" if change.param_type else ""
req_part = f" · {change._required_tag()}" if change._required_tag() else ""
lines = [f"{branch} `{change.param_name}`{type_part}{req_part} {change._change_tag()}"]
if desc:
lines.append(f"> 说明:{desc}")
if change.change_type.value == "modified" and change.detail:
lines.append(f"> 变更:{change.detail}")
if change.change_type.value == "renamed":
lines.append(f"> `{change.old_name}` → `{change.param_name}`")
return lines
def _format_body_dto_groups(changes: List[ParameterChange]) -> List[str]:
"""按 DTO 分组展示 @RequestBody 一级字段。"""
if not changes:
return ['<font color="comment">无</font>']
groups: OrderedDict[Tuple[str, str], List[ParameterChange]] = OrderedDict()
for change in changes: for change in changes:
lines.append(change.to_table_row()) key = _body_dto_group_key(change)
groups.setdefault(key, []).append(change)
lines: List[str] = ["", f"共 **{len(groups)}** 个类对象 · **{len(changes)}** 项字段变更", ""]
for (param_name, dto_name), group in groups.items():
label = param_name or "body"
dto_part = f" · `{dto_name}`" if dto_name else ""
lines.append(f"**{label}**{dto_part}")
lines.append("")
for i, change in enumerate(group):
lines.extend(_format_body_field_line(change, is_last=(i == len(group) - 1)))
lines.append("")
if lines and lines[-1] == "":
lines.pop()
return lines return lines
def _format_param_details_section(report: EndpointChangeReport) -> List[str]: def _format_param_details_section(report: EndpointChangeReport) -> List[str]:
"""生成接口参数变动详情区块(对齐 model.md""" """生成接口参数变动详情区块。"""
body_changes = [c for c in report.parameter_changes if c.source == "body"] 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"] regular_changes = [c for c in report.parameter_changes if c.source != "body"]
lines = ["", "---", "", "## 接口参数变动详情", "", "---", ""] lines = ["", "---------------------------------------", "", "#### 【接口参数变动详情", ""]
if body_changes: if body_changes:
lines.append("### 类对象变更") lines.append("**类对象变更(一级字段)**")
lines.append("") lines.extend(_format_body_dto_groups(body_changes))
lines.append("- **参数变更列表:**")
lines.extend(_format_param_table(body_changes))
lines.append("") lines.append("")
if regular_changes: if regular_changes:
lines.append("### 普通参数变更(非对象字段)") lines.append("**普通参数变更**")
lines.append("") lines.extend(_format_param_change_list(regular_changes))
lines.append("- **参数变更列表:**")
lines.extend(_format_param_table(regular_changes))
lines.append("") lines.append("")
if not body_changes and not regular_changes: if not body_changes and not regular_changes:
@@ -357,7 +398,7 @@ def send_parameter_change_notification(
# 构建参数变更通知(只包含参数变更报告,对齐 model.md # 构建参数变更通知(只包含参数变更报告,对齐 model.md
parts: List[str] = [] parts: List[str] = []
parts.append("# 【API参数变更通知】") parts.append("# 【API参数变更通知】")
parts.append(f"- **修改人:** {push_user if push_user.startswith('@') else '@' + push_user}") parts.append(f"- **修改人:** {push_user}")
parts.append(f"- **修改时间:** {push_time}") parts.append(f"- **修改时间:** {push_time}")
parts.append("") parts.append("")
for report in changed_reports: for report in changed_reports:

View File

@@ -2,9 +2,17 @@
# AI-Check 配置文件(位于 .gitea/ 目录,与业务代码解耦) # AI-Check 配置文件(位于 .gitea/ 目录,与业务代码解耦)
# ============================================================ # ============================================================
# ---------- API 变动检查 ----------
# 总开关false 时跳过 Controller 接口参数变更检测(不对比、不通知)
check:
enabled: true
# 业务 Java 源码目录(相对仓库根目录) # 业务 Java 源码目录(相对仓库根目录)
# 单模块: src/main/java # 单模块: source_dir: "src/main/java"
# 多模块: ftb/src/main/java # 多模块: 使用 source_dirs优先于 source_dir
source_dirs:
- "jnpf-ftb/jnpf-ftb-biz/src/main/java"
- "jnpf-ftb/jnpf-ftb-entity/src/main/java"
source_dir: "ftb/src/main/java" source_dir: "ftb/src/main/java"
# ---------- 企业微信机器人 ---------- # ---------- 企业微信机器人 ----------

View File

@@ -22,8 +22,8 @@
- [删除] 属性: `attr2` 说明: {说明} - [删除] 属性: `attr2` 说明: {说明}
- [修改] 属性: `attr3` 说明: {说明} - [修改] 属性: `attr3` 说明: {说明}
### 普通参数变更(非对象字段) ### 参数变更
- **参数变更列表:** - **变更列表:**
| 字段 | 说明 | 变更 | | 字段 | 说明 | 变更 |
|------|------|------| |------|------|------|

View File

@@ -2,7 +2,9 @@
<module type="JAVA_MODULE" version="4"> <module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true"> <component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output /> <exclude-output />
<content url="file://$MODULE_DIR$" /> <content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/jnpf-ftb" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
</component> </component>

17
.idea/sqldialects.xml generated Normal file
View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="SqlDialectMappings">
<file url="file://$PROJECT_DIR$/jnpf-ftb/jnpf-ftb-biz/src/main/resources/ftb_certificate_instance_upgrade_template_status.sql" dialect="GenericSQL" />
<file url="file://$PROJECT_DIR$/jnpf-ftb/jnpf-ftb-biz/src/main/resources/sql/certificate/ftb_certificate_instance.sql" dialect="GenericSQL" />
<file url="file://$PROJECT_DIR$/jnpf-ftb/jnpf-ftb-biz/src/main/resources/sql/certificate/ftb_certificate_instance_upgrade_health_certificate_data.sql" dialect="GenericSQL" />
<file url="file://$PROJECT_DIR$/jnpf-ftb/jnpf-ftb-biz/src/main/resources/sql/franchisee/base_dictionary_franchisee_nature.sql" dialect="GenericSQL" />
<file url="file://$PROJECT_DIR$/jnpf-ftb/jnpf-ftb-biz/src/main/resources/sql/franchisee/base_dictionary_industry_param.sql" dialect="GenericSQL" />
<file url="file://$PROJECT_DIR$/jnpf-ftb/jnpf-ftb-biz/src/main/resources/sql/franchisee/ftb_franchisee.sql" dialect="GenericSQL" />
<file url="file://$PROJECT_DIR$/jnpf-ftb/jnpf-ftb-biz/src/main/resources/sql/franchisee/ftb_franchisee_batch_insert_5000_with_region.sql" dialect="GenericSQL" />
<file url="file://$PROJECT_DIR$/jnpf-ftb/jnpf-ftb-biz/src/main/resources/sql/ftb_certificate_instance_upgrade_business_license_from_base_organize.sql" dialect="GenericSQL" />
<file url="file://$PROJECT_DIR$/jnpf-ftb/jnpf-ftb-biz/src/main/resources/sql/ftb_certificate_instance_upgrade_org_store_missing.sql" dialect="GenericSQL" />
<file url="file://$PROJECT_DIR$/jnpf-ftb/jnpf-ftb-biz/src/main/resources/sql/ftb_store_add_store_type_franchisee.sql" dialect="GenericSQL" />
<file url="file://$PROJECT_DIR$/jnpf-ftb/jnpf-ftb-biz/src/main/resources/sql/storecertificatephoto/base_param.sql" dialect="GenericSQL" />
<file url="file://$PROJECT_DIR$/jnpf-ftb/jnpf-ftb-biz/src/main/resources/sql/storecertificatephoto/ftb_store_certificate_photo.sql" dialect="GenericSQL" />
</component>
</project>

View File

@@ -1,2 +0,0 @@
# 示例 Spring Controller用于本地测试 AST 解析
# 将此目录结构复制到你的 Java 项目中进行验证

View File

@@ -1,44 +0,0 @@
package com.example.controller;
import org.springframework.web.bind.annotation.*;
/**
* 示例 UserController用于测试 API 变更检测。
*/
@RestController
@RequestMapping("/api/users")
public class UserController {
/**
* 查询用户详情 — 含多种参数类型,便于测试增删改检测。
*/
@GetMapping("/{id}")
public String getUser(@PathVariable("id") String id, @RequestParam(value = "test", required = false, defaultValue = "false") Boolean includeDisabled) {
return "ok";
}
/**
* 新增用户
*/
@PostMapping("/createUser")
public String createUser(@RequestBody UserCreateRequest request) {
return "created";
}
/**
* 更新用户
*/
@PutMapping("/{id}")
public String updateUser(@PathVariable("id") Long id, @RequestBody UserCreateRequest request) {
return "updated";
}
/**
* 删除用户
*/
@DeleteMapping("/{id}")
public String deleteUser(@PathVariable("id") Long id) {
return "deleted";
}
}

View File

@@ -1,26 +0,0 @@
package com.example.controller;
/**
* 示例请求体 DTO测试 @RequestBody 字段展开。
*/
public class UserCreateRequest {
private String userName;
private Boolean userType;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Boolean getUserType() {
return userType;
}
public void setUserType(Boolean userType) {
this.userType = userType;
}
}

View File

@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.jnpf</groupId>
<artifactId>jnpf-ftb</artifactId>
<version>3.4.7-RELEASE</version>
</parent>
<artifactId>jnpf-ftb-api</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.jnpf</groupId>
<artifactId>jnpf-ftb-entity</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.jnpf</groupId>
<artifactId>jnpf-duty-entity</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.jnpf</groupId>
<artifactId>jnpf-common-feign</artifactId>
</dependency>
<dependency>
<groupId>com.jnpf</groupId>
<artifactId>jnpf-permission-entity</artifactId>
<version>3.4.7-RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.jnpf</groupId>
<artifactId>jnpf-tenant-entity</artifactId>
<version>3.4.7-RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>9</source>
<target>9</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,72 @@
package jnpf.account;
import jnpf.account.fallback.PTenantAccountApiFallBackFactory;
import jnpf.base.ActionResult;
import jnpf.exception.HandleException;
import jnpf.model.TenantGenerateDefaultAvatarVO;
import jnpf.model.personnels.dto.turnover.SaveTenantUserForm;
import jnpf.model.personnels.req.roster.UserAccountDto;
import jnpf.model.user.GenerateHeadForm;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.util.List;
@FeignClient(name = "jnpf-tenant", fallbackFactory = PTenantAccountApiFallBackFactory.class, path = "/tenantUser")
public interface PTenantAccountApi {
@PutMapping("/batchAddUserAccount")
ActionResult<List<UserAccountDto>> batchAddUserAccount(@RequestBody List<UserAccountDto> userAccountForms);
@PutMapping("/batchDisabledUserAccount")
ActionResult<List<UserAccountDto>> batchDisabledUserAccount(@RequestBody List<UserAccountDto> userAccountForms);
@GetMapping("/generateDefaultAvatar")
ActionResult generateDefaultAvatar(@RequestParam("name") String name) throws IOException;
/**
* 批量异步生成头像 调用方自己要触发保底
* @param names 用户名
* @return
*/
@PostMapping("/batch/generate/default/avatar")
List<TenantGenerateDefaultAvatarVO> batchGenerateDefaultAvatar(@RequestBody List<String> names);
/**
* 用户状态修改
* @param saveTenantUserForm
* @return
*/
@PutMapping("/updateJobStatus")
ActionResult updateJobStatus(@RequestBody SaveTenantUserForm saveTenantUserForm);
@PutMapping("/userInfoSynchronous")
ActionResult userInfoSynchronous(@RequestBody SaveTenantUserForm saveTenantUserForm);
@DeleteMapping("/deleteUser/{id}")
ActionResult deleteUser(@PathVariable("id") String id);
/**
* 删除用户(同步删除租户用户)
*
* @param userId 用户ID
* @return ActionResult
*/
@DeleteMapping("/deleteUserWithPlatform/{userId}")
Boolean deleteUserWithPlatform(@PathVariable("userId") String userId);
/**
* 批量删除用户
*/
@DeleteMapping("/deleteUsers")
ActionResult<Void> deleteUsers(@RequestBody List<String> userIds) ;
@PostMapping("/generateDefaultAvatarCustomFilename")
ActionResult generateDefaultAvatar(@RequestBody GenerateHeadForm generateHeadForm) throws IOException;
}

View File

@@ -0,0 +1,72 @@
package jnpf.account.fallback;
import jnpf.account.PTenantAccountApi;
import jnpf.base.ActionResult;
import jnpf.exception.HandleException;
import jnpf.model.TenantGenerateDefaultAvatarVO;
import jnpf.model.personnels.dto.turnover.SaveTenantUserForm;
import jnpf.model.personnels.req.roster.UserAccountDto;
import jnpf.model.user.GenerateHeadForm;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import java.util.List;
@Slf4j
public class PTenantAccountApiFallBack implements PTenantAccountApi {
@Override
public ActionResult<List<UserAccountDto>> batchAddUserAccount(List<UserAccountDto> userAccountForms) {
log.error("调用批量添加用户接口失败,降级");
return null;
}
@Override
public ActionResult<List<UserAccountDto>> batchDisabledUserAccount(List<UserAccountDto> userAccountForms) {
return null;
}
@Override
public ActionResult generateDefaultAvatar(String name) throws IOException {
log.error("调用生成默认头像接口失败,降级");
return null;
}
@Override
public List<TenantGenerateDefaultAvatarVO> batchGenerateDefaultAvatar(List<String> names) {
log.error("调用生成默认头像接口失败,降级");
return List.of();
}
@Override
public ActionResult updateJobStatus(SaveTenantUserForm saveTenantUserForm) {
return null;
}
@Override
public ActionResult userInfoSynchronous(SaveTenantUserForm saveTenantUserForm) {
log.error("调用同步用户信息接口失败,降级");
return null;
}
@Override
public ActionResult deleteUser(String id) {
return null;
}
@Override
public Boolean deleteUserWithPlatform(String userId) {
log.error("调用删除租户用户接口失败,降级");
return false;
}
@Override
public ActionResult<Void> deleteUsers(List<String> userIds) {
return null;
}
@Override
public ActionResult generateDefaultAvatar(GenerateHeadForm generateHeadForm) throws IOException {
return null;
}
}

View File

@@ -0,0 +1,22 @@
package jnpf.account.fallback;
import feign.FeignException;
import feign.Request;
import jnpf.account.PTenantAccountApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class PTenantAccountApiFallBackFactory implements FallbackFactory<PTenantAccountApi> {
@Override
public PTenantAccountApi create(Throwable cause) {
log.error("服务降级了");
cause.printStackTrace();
log.error(cause.getMessage(), cause);
return new PTenantAccountApiFallBack();
}
}

View File

@@ -0,0 +1,35 @@
package jnpf.attendance;
import jnpf.attendance.fallback.AttendanceApiFallback;
import jnpf.model.attendance.vo.attendance.AttendanceToThousandsFacesVo;
import jnpf.util.NoDataSourceBind;
import org.apache.ibatis.annotations.Param;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
* describe
*
* @author HuangLinPan
* @date 2023/11/27
*/
@FeignClient(name = "jnpf-ftb", fallbackFactory = AttendanceApiFallback.class, path = "/attendance")
public interface AttendanceApi {
@PostMapping(value = "/invalidationCoupons")
@NoDataSourceBind
Boolean invalidationCoupons(@RequestParam(value = "tenantId") String tenantId);
// @PostMapping(value = "/overtimeVouchers")
// @NoDataSourceBind
// Boolean overtimeVouchers(@RequestParam(value = "tenantId") String tenantId);
@PostMapping(value = "/storageRest")
Boolean storageRest(@RequestParam("tenantId") String tenantId);
@PostMapping(value = "/attendanceToThousandsFaces")
AttendanceToThousandsFacesVo attendanceToThousandsFaces();
}

View File

@@ -0,0 +1,27 @@
package jnpf.attendance;
import io.swagger.v3.oas.annotations.Operation;
import jnpf.attendance.fallback.AttendanceUserApiFallback;
import jnpf.base.ActionResult;
import jnpf.model.thousandsfaces.TodayWorkVo;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import java.util.List;
@FeignClient(name = "jnpf-ftb", fallbackFactory = AttendanceUserApiFallback.class, path = "/attendance/confirm")
public interface AttendanceConfirmApi {
@Operation(summary = "自动生成考勤确认数据")
@GetMapping(value = "/autoConfirm")
ActionResult<Boolean> autoCreateConfirm();
@Operation(summary = "逾期自动确认")
@GetMapping(value = "/confirmAutoSlippage")
ActionResult<Boolean> confirmAutoSlippage();
@Operation(summary = "今日工作-考勤确认列表(0-待确认 1-已确认 2-已逾期)")
@GetMapping(value = "/getTodayWorkConfirmList")
List<TodayWorkVo> getTodayWorkConfirmList();
}

View File

@@ -0,0 +1,63 @@
package jnpf.attendance;
import jnpf.attendance.fallback.AttendanceDailyRuleApiFallback;
import jnpf.base.ActionResult;
import jnpf.util.NoDataSourceBind;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.Date;
import java.util.List;
/**
* 组队动态
*
* @author JNPF开发平台组
* @version V3.1.0
* @copyright 引迈信息技术有限公司https://www.jnpfsoft.com
* @date 2021-03-24
*/
@FeignClient(name = "jnpf-ftb", fallbackFactory = AttendanceDailyRuleApiFallback.class, path = "/arranging/work")
public interface AttendanceDailyRuleApi {
/**
* 定时执行初始化下个月固定排班
*/
@PostMapping("initFixedScheduleRule")
ActionResult initFixedScheduleRule(@RequestParam(value = "tenantId") String tenantId);
/**
* 定时执行初始化下个月固定排班
*/
@PostMapping("autoGrantBalance")
ActionResult autoGrantBalance(@RequestParam(value = "tenantId") String tenantId);
/**
* 用户是否排班
*
* @param tenantId 租户ID
* @param userId 用户ID
* @return
*/
@NoDataSourceBind
@GetMapping("userIsScheduling")
ActionResult<Boolean> userIsScheduling(@RequestParam("tenantId") String tenantId, @RequestParam("userId") String userId);
@PostMapping("userIsSchedulingOrdinary")
ActionResult<List<String>> userIsSchedulingOrdinary(@RequestBody List<String> organizeIds);
/**
* 判断用户指定时间范围内是否排班
*
* @param userId 用户ID
* @param start 开始时间
* @param end 结束时间
* @return
*/
@GetMapping("hasRuleByUserIdAndTime")
ActionResult<Boolean> hasRuleByUserIdAndTime(@RequestParam("userId") String userId, @RequestParam("start") Date start, @RequestParam("end") Date end);
}

View File

@@ -0,0 +1,59 @@
package jnpf.attendance;
import jnpf.attendance.dto.AttendanceUserGroupVo;
import jnpf.attendance.dto.AttendanceUserListGroupVO;
import jnpf.attendance.fallback.AttendanceGroupApiFallback;
import jnpf.base.ActionResult;
import jnpf.entity.AttendanceGroup;
import jnpf.model.attendance.vo.AttendanceGroupVo;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
/**
* @Title: 考情组api
* @Author: peng.hao
* @create: 2024/4/23:16:09
*/
@FeignClient(name = "jnpf-ftb",fallbackFactory = AttendanceGroupApiFallback.class,path = "/group")
public interface AttendanceGroupApi {
/**
* 获取考勤组名称
* @param groupId 考勤组Id
*
*/
@GetMapping("/queryTheNameOfTheAttendanceGroup")
AttendanceGroup queryTheNameOfTheAttendanceGroup(@RequestParam(value = "groupId") String groupId);
@GetMapping("/attendanceUserGroup")
List<AttendanceUserGroupVo> getAttendanceUserGroup(@RequestParam("userIds") List<String> userIds);
@GetMapping("/getGroupListByOrgId")
List<AttendanceGroup> getGroupListByOrgId(@RequestParam("organizeId") String organizeId);
/**
* 批量获取用户绑定的考勤组 ,包含全名称 xxx/xxx/xxx
* @param userIds 用户ids
*
*/
@PostMapping("/list/user_bound")
ActionResult<List<AttendanceUserListGroupVO>> getAttendanceUserListGroupVO(@RequestBody List<String> userIds);
/**
* 详情---获取一个考勤组
* @param organizeName 组织名称
* @param groupName 考勤组名称
* @return 一个考勤组
*/
@GetMapping("/info/organize_group/name")
ActionResult<AttendanceGroupVo> getAttendanceGroupByName(@RequestParam("organizeName") String organizeName, @RequestParam("groupName") String groupName);
@GetMapping("/checkScheduling")
boolean checkScheduling();
}

View File

@@ -0,0 +1,25 @@
package jnpf.attendance;
import jnpf.attendance.fallback.AttendanceApiFallback;
import jnpf.model.attendance.vo.attendance.AttendanceToThousandsFacesVo;
import jnpf.util.NoDataSourceBind;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
* describe
*
* @author HuangLinPan
* @date 2023/11/27
*/
@FeignClient(name = "jnpf-ftb", fallbackFactory = AttendanceApiFallback.class, path = "/arranging/line/scheduling/config")
public interface AttendanceLineSchedulingConfigApi {
@GetMapping(value = "/noticeLineScheduling")
Boolean noticeLineScheduling(@RequestParam("tenantId") String tenantId);
}

View File

@@ -0,0 +1,24 @@
package jnpf.attendance;
import jnpf.attendance.fallback.AttendanceSimulateDataApiFallback;
import jnpf.attendance.fallback.FtbClockInApiFallback;
import jnpf.util.NoDataSourceBind;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
* 打卡api
*
* @author yanwenfu
* @create 2023-12-04
*/
@FeignClient(name = "jnpf-ftb", fallbackFactory = AttendanceSimulateDataApiFallback.class, path = "/attendance/simulateData")
public interface AttendanceSimulateDataApi {
/**
* 打卡
* @return java.lang.Object
*/
@PostMapping(value = "/clockIn")
void clockIn(@RequestParam(value = "tenantId") String tenantId) throws Exception;
}

View File

@@ -0,0 +1,39 @@
package jnpf.attendance;
import jnpf.attendance.dto.GroupUpdateByUserDTO;
import jnpf.attendance.fallback.AttendanceUserApiFallback;
import jnpf.base.ActionResult;
import jnpf.util.NoDataSourceBind;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
/**
* describe
*
* @author HuangLinPan
* @date 2023/11/27
*/
@FeignClient(name = "jnpf-ftb", fallbackFactory = AttendanceUserApiFallback.class, path = "/user")
public interface AttendanceUserApi {
/**
* 花名册考勤组变更
*
* @param groupUpdateByUserDTO
* @return
*/
@PostMapping("groupUpdateByPersonnel")
ActionResult groupUpdateByPersonnel(@RequestBody GroupUpdateByUserDTO groupUpdateByUserDTO);
/**
* 借调考勤组变动通知
* @param tenantId
* @return
*/
@NoDataSourceBind
@GetMapping(value = "/userGroupUpdateBySecondNotice")
ActionResult<Boolean> userGroupUpdateBySecondNotice(@RequestParam(value = "tenantId") String tenantId);
}

View File

@@ -0,0 +1,44 @@
package jnpf.attendance;
import jnpf.attendance.fallback.FtbClockInApiFallback;
import jnpf.util.NoDataSourceBind;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
* 打卡api
*
* @author yanwenfu
* @create 2023-12-04
*/
@FeignClient(name = "jnpf-ftb", fallbackFactory = FtbClockInApiFallback.class, path = "/attendance/clockIn")
public interface FtbClockInApi {
@GetMapping(value = "/daily-rule-change/execute")
Boolean dailyRuleChangeExecute();
@PostMapping(value = "/absenceRecord")
@NoDataSourceBind
Boolean generateFtbAbsenceRecord(@RequestParam(value = "tenantId") String tenantId);
@PostMapping(value = "/absenceTask")
@NoDataSourceBind
Boolean generateAbsenceTask(@RequestParam(value = "tenantId") String tenantId);
/**
* 生成打卡提醒记录
* @return java.lang.Boolean
*/
@PostMapping(value = "/remindRecord")
@NoDataSourceBind
Boolean generateBeforeWorkRemind(@RequestParam(value = "tenantId") String tenantId);
@PostMapping(value = "/repairNum")
@NoDataSourceBind
Boolean generateRepairNum(@RequestParam(value = "tenantId") String tenantId);
@PostMapping(value = "/continuousCheck")
Boolean continuousCheck(@RequestParam(value = "tenantId") String tenantId);
}

View File

@@ -0,0 +1,108 @@
package jnpf.attendance;
import io.swagger.v3.oas.annotations.Operation;
import jnpf.attendance.dto.*;
import jnpf.attendance.fallback.FtbStatisticsApiFallback;
import jnpf.base.ActionResult;
import jnpf.model.attendance.dto.DayStatisticsDto;
import jnpf.model.attendance.dto.SalaryAttendanceSupportDto;
import jnpf.model.attendance.vo.attendance.AttendanceCustomizeTableVo;
import jnpf.model.attendance.vo.attendance.DayStatisticsPageListVo;
import jnpf.model.attendance.vo.attendance.DayStatisticsVo;
import jnpf.model.attendance.vo.attendance.SalaryAttendanceSupportVo;
import jnpf.util.NoDataSourceBind;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.Date;
import java.util.List;
import java.util.Map;
@FeignClient(name = "jnpf-ftb", fallbackFactory = FtbStatisticsApiFallback.class, path = "/attendance/statistics")
public interface FtbStatisticsApi {
@Operation(summary = "用户日统计数据初始化")
@GetMapping(value = "/userDayStatisticsInit")
ActionResult<Boolean> userDayStatisticsInit(@RequestParam(value = "tenantId") String tenantId);
@Operation(summary = "个人考勤日报通知")
@GetMapping(value = "/dayStatisticsNotice")
ActionResult<Boolean> dayStatisticsNotice(@RequestParam(value = "tenantId") String tenantId);
@NoDataSourceBind
@Operation(summary = "个人统计月报通知")
@GetMapping(value = "/monthStatisticsNotice")
ActionResult<Boolean> monthStatisticsNotice(@RequestParam(value = "tenantId") String tenantId);
@NoDataSourceBind
@Operation(summary = "团队统计月报通知")
@GetMapping(value = "/teamMonthStatisticsNotice")
ActionResult<Boolean> teamMonthStatisticsNotice(@RequestParam(value = "tenantId") String tenantId);
@Operation(summary = "连续未排班通知")
@GetMapping(value = "/consentUnscheduledNotice")
void consentUnscheduledNotice(@RequestParam(value = "tenantId") String tenantId);
@Operation(summary = "考勤封账-自动封账定时器")
@PutMapping(value = "/autoSealTimer")
ActionResult<Boolean> autoSealTimer(@RequestParam(value = "tenantId") String tenantId);
@Operation(summary = "计算考勤组平均工时(实际出勤工时)")
@PostMapping(value = "/countAttendanceAvgHours")
List<AttendanceCountAvgHoursVo> countAttendanceAvgHours(@Valid @RequestBody AttendanceCountAvgHoursDto dto);
@Operation(summary = "获取多考勤组月度统计数据")
@PostMapping(value = "/getAttendanceAvgHoursDetails")
ActionResult<MonthStatsDetailsVo> getAttendanceAvgHoursDetails(@Valid @RequestBody MonthStatsDetailsDto dto);
@Operation(summary = "获取多考勤组月度人均工时折线图")
@PostMapping(value = "/getAttendanceMonthPerCapita")
ActionResult<List<MonthStatsPerCapitaVo>> getAttendanceMonthPerCapita(@Valid @RequestBody MonthStatsDetailsDto dto);
@Operation(summary = "获取多考勤组月度日常情况")
@PostMapping(value = "/getAttendanceDailySituation")
ActionResult<List<MonthStatsDailySituationVo>> getAttendanceDailySituation(@Valid @RequestBody MonthStatsDetailsDto dto);
@Operation(summary = "获取多考勤组月度考勤工时排行")
@PostMapping(value = "/getAttendanceHoursRanking")
ActionResult<List<MonthStatsHoursRankingVo>> getAttendanceHoursRanking(@Valid @RequestBody MonthStatsDetailsDto dto);
@Operation(summary = "获取多考勤组月度全勤情况")
@PostMapping(value = "/getAttendanceFullSituation")
ActionResult<List<MonthStatsFullSituationVo>> getAttendanceFullSituation(@Valid @RequestBody MonthStatsDetailsDto dto);
@Operation(summary = "获取多考勤组月度异常情况")
@PostMapping(value = "/getAttendanceAbnormalCondition")
ActionResult<MonthStatsAbnormalConditionVo> getAttendanceAbnormalCondition(@Valid @RequestBody MonthStatsDetailsDto dto);
@Operation(summary = "获取多考勤组月度加班情况")
@PostMapping(value = "/getAttendanceOvertimeSituation")
ActionResult<List<MonthStatsOvertimeSituationVo>> getAttendanceOvertimeSituation(@Valid @RequestBody MonthStatsDetailsDto dto);
@Operation(summary = "薪酬考勤数据支持")
@PostMapping(value = "/salaryAttendanceSupport")
Map<String, SalaryAttendanceSupportVo> salaryAttendanceSupport(@Valid @RequestBody SalaryAttendanceSupportDto dto);
@Operation(summary = "考勤统计数据日度列表表头(薪酬)")
@PostMapping(value = "/attendanceDayStaTable")
List<AttendanceCustomizeTableVo> attendanceDayStaTable();
@Operation(summary = "考勤统计数据日度列表")
@PostMapping(value = "/attendanceDayStaList")
List<DayStatisticsPageListVo> attendanceDayStaList(@Valid @RequestBody SalaryAttendanceSupportDto dto);
@Operation(summary = "获取日出勤信息")
@NoDataSourceBind
@PostMapping(value = "/getAttendanceDayStaList")
List<DayStatisticsVo> getAttendanceDayStaList(@Valid @RequestBody DayStatisticsDto dto);
@Operation(summary = "获取各维度出勤人数")
@PostMapping(value = "/getDimensionsAttendanceCountMap")
Map<String, List<DateDimensionsRangeVo>> getDimensionsAttendanceCountMap(@Valid @RequestBody DimensionsAttendanceCountDto dto);
@Operation(summary = "获取各维度出勤人数")
@PostMapping(value = "/getDimensionsAttendanceDayCountMap")
Map<String, Map<Date, Integer>> getDimensionsAttendanceDayCountMap(@Valid @RequestBody DimensionsAttendanceDayCountDto dto);
}

View File

@@ -0,0 +1,32 @@
package jnpf.attendance.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import java.util.List;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AttendanceCountAvgHoursDto {
/**
* 组织ID集合
*/
@NotEmpty(message = "组织ID集合不能为空")
private List<String> orgIds;
/**
* 开始月份(yyyyMM)
*/
@NotBlank(message = "开始月份不能为空")
private String startMonth;
/**
* 结束月份(yyyyMM)
*/
@NotBlank(message = "结束月份不能为空")
private String endMonth;
}

View File

@@ -0,0 +1,27 @@
package jnpf.attendance.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AttendanceCountAvgHoursVo {
/**
* 月份
*/
@NotBlank(message = "月份不能为空")
private String month;
/**
* 平均值
*/
@NotNull(message = "平均值不能为空")
private BigDecimal avgHours = BigDecimal.ZERO;
}

View File

@@ -0,0 +1,24 @@
package jnpf.attendance.dto;
import lombok.Data;
/**
* @Author huanglinpan
* @Date 2024/4/23 17:31
* @Version 1.0 (版本号)
*/
@Data
public class AttendanceUserGroupVo {
/**
* 考勤组Id
*/
private String groupId;
/**
* 考勤组名称
*/
private String groupName;
/**
* 用户Id
*/
private String userId;
}

View File

@@ -0,0 +1,34 @@
package jnpf.attendance.dto;
import lombok.Data;
import java.io.Serializable;
/**
* todo
*
* @author Flynn Chan
* @create 2024-05-17
*/
@Data
public class AttendanceUserListGroupVO implements Serializable {
/**
* 考勤组id
*/
private String groupId;
/**
* 考勤组名称
*/
private String groupName;
/**
* 考勤组名称
*/
private String groupFullName;
/**
* 用户Id
*/
private String userId;
}

View File

@@ -0,0 +1,30 @@
package jnpf.attendance.dto;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 查询维度枚举
*
* @author Flynn Chan
* @create 2025-02-13
*/
@AllArgsConstructor
@Getter
public enum CompareTypeEnums {
CURRENT(1, "本期"),
YOY(2, "同比"),
MOM(3, "环比");
private final int value;
private final String text;
public static CompareTypeEnums getTypeEnums(int value) {
CompareTypeEnums[] values = CompareTypeEnums.values();
for (CompareTypeEnums typeEnums : values) {
if (typeEnums.getValue() == value) {
return typeEnums;
}
}
return null;
}
}

View File

@@ -0,0 +1,31 @@
package jnpf.attendance.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotNull;
import java.util.Date;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class DateDimensionsRangeDto {
/**
* 查询维度枚举
*/
@NotNull(message = "查询维度不能为空")
private CompareTypeEnums typeEnums;
/**
* 开始时间
*/
@NotNull(message = "开始时间不能为空")
private Date startDate;
/**
* 结束时间
*/
@NotNull(message = "结束时间不能为空")
private Date endDate;
}

View File

@@ -0,0 +1,24 @@
package jnpf.attendance.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotNull;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class DateDimensionsRangeVo {
/**
* 查询维度枚举
*/
@NotNull(message = "查询维度不能为空")
private CompareTypeEnums typeEnums;
/**
* 出勤人数
*/
private Integer count;
}

View File

@@ -0,0 +1,26 @@
package jnpf.attendance.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotEmpty;
import java.util.List;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class DimensionsAttendanceCountDto {
/**
* 系统门店ID集合
*/
@NotEmpty(message = "系统门店ID集合不能为空")
private List<String> storeIds;
/**
* 时间维度集合
*/
@NotEmpty(message = "时间维度集合不能为空")
private List<DateDimensionsRangeDto> dimensionsRangeList;
}

View File

@@ -0,0 +1,33 @@
package jnpf.attendance.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Date;
import java.util.List;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class DimensionsAttendanceDayCountDto {
/**
* 系统门店ID集合
*/
@NotEmpty(message = "系统门店ID集合不能为空")
private List<String> storeIds;
/**
* 开始时间
*/
@NotNull(message = "开始时间不能为空")
private Date startDate;
/**
* 结束时间
*/
@NotNull(message = "结束时间不能为空")
private Date endDate;
}

View File

@@ -0,0 +1,28 @@
package jnpf.attendance.dto;
import lombok.Data;
import java.util.Date;
import java.util.List;
@Data
public class GroupUpdateByUserDTO {
/**
* 1入职 2离职 3调岗 4晋升 5批量删除
*/
private Integer type;
/**
* 目标考勤组id
*/
private String toGroupId;
/**
* 用户id集合
*/
private List<String> userIds;
private String tenantId;
/**
* 实际入职日期,yyyy-MM-dd
*/
private Date joiningDate;
}

View File

@@ -0,0 +1,55 @@
package jnpf.attendance.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MonthStatsAbnormalConditionVo {
/**
* 正常次数
*/
private Integer normalCount = 0;
/**
* 正常次数占比
*/
private BigDecimal normalPercent = BigDecimal.ZERO;
/**
* 迟到次数
*/
private Integer lateCount = 0;
/**
* 迟到次数占比
*/
private BigDecimal latePercent = BigDecimal.ZERO;
/**
* 早退次数
*/
private Integer earlyCount = 0;
/**
* 早退次数占比
*/
private BigDecimal earlyPercent = BigDecimal.ZERO;
/**
* 缺卡次数
*/
private Integer absenceCardCount = 0;
/**
* 缺卡次数占比
*/
private BigDecimal absenceCardPercent = BigDecimal.ZERO;
/**
* 旷工次数
*/
private Integer absenceCount = 0;
/**
* 旷工次数占比
*/
private BigDecimal absencePercent = BigDecimal.ZERO;
}

View File

@@ -0,0 +1,23 @@
package jnpf.attendance.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MonthStatsDailySituationVo {
/**
* 出勤类型
*/
private String typeName;
/**
* 工时(天)
*/
private BigDecimal avgDays;
}

View File

@@ -0,0 +1,27 @@
package jnpf.attendance.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import java.util.List;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MonthStatsDetailsDto {
/**
* 考勤组ID集合
*/
@NotEmpty(message = "考勤组ID集合不能为空")
private List<String> groupIds;
/**
* 月份(yyyyMM)
*/
@NotBlank(message = "开始月份不能为空")
private String month;
}

View File

@@ -0,0 +1,63 @@
package jnpf.attendance.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MonthStatsDetailsVo {
/**
* 人均工时
*/
private BigDecimal avgHours = BigDecimal.ZERO;
/**
* 人均工时同比增长(正负表示增减,为空表示没有可对比性展示--)
*/
private BigDecimal avgHoursOnYear;
/**
* 人均工时环比增长(正负表示增减,为空表示没有可对比性展示--)
*/
private BigDecimal avgHoursOnMonth;
/**
* 人均加班工时
*/
private BigDecimal avgOverTimeHours = BigDecimal.ZERO;
/**
* 人均请假天数
*/
private BigDecimal avgLeaveDays = BigDecimal.ZERO;
/**
* 人均请假天数同比增长(正负表示增减,为空表示没有可对比性展示--)
*/
private BigDecimal avgLeaveDaysOnYear;
/**
* 人均请假天数环比增长(正负表示增减,为空表示没有可对比性展示--)
*/
private BigDecimal avgLeaveDaysMonth;
/**
* 人均旷工天数
*/
private BigDecimal avgAbsentDays = BigDecimal.ZERO;
/**
* 迟到人数
*/
private BigDecimal lateCount = BigDecimal.ZERO;
/**
* 迟到人数同比增长(正负表示增减,为空表示没有可对比性展示--)
*/
private BigDecimal lateCountOnYear;
/**
* 迟到人数环比增长(正负表示增减,为空表示没有可对比性展示--)
*/
private BigDecimal lateCountOnMonth;
/**
* 早退人数
*/
private BigDecimal earlyCount = BigDecimal.ZERO;
}

View File

@@ -0,0 +1,31 @@
package jnpf.attendance.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MonthStatsFullSituationVo {
/**
* 日期
*/
private String day;
/**
* 考勤组人数
*/
private Integer groupUserCount;
/**
* 全勤人数
*/
private Integer fullCount;
/**
* 全勤占比
*/
private BigDecimal fullRatio;
}

View File

@@ -0,0 +1,23 @@
package jnpf.attendance.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MonthStatsHoursRankingVo {
/**
* 用户名
*/
private String userName;
/**
* 工时(小时)
*/
private BigDecimal hours;
}

View File

@@ -0,0 +1,32 @@
package jnpf.attendance.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MonthStatsOvertimeSituationVo {
/**
* 日期(MM.dd)
*/
private String day;
/**
* 加班工时(小时)
*/
private BigDecimal overtimeHours;
/**
* 加班工时同比增长(正负表示增减,为空表示没有可对比性展示--)
*/
private BigDecimal overtimeHoursOnYear;
/**
* 加班工时环比增长(正负表示增减,为空表示没有可对比性展示--)
*/
private BigDecimal overtimeHoursOnMonth;
}

View File

@@ -0,0 +1,23 @@
package jnpf.attendance.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MonthStatsPerCapitaVo {
/**
* 日期(MM.dd)
*/
private String day;
/**
* 人均工时(小时)
*/
private BigDecimal avgHours;
}

View File

@@ -0,0 +1,27 @@
package jnpf.attendance.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MonthStatsSituationVo {
/**
* 日期MM.dd
*/
private String day;
/**
* 总人数
*/
private Integer totalCount;
/**
* 全勤人数
*/
private Integer onTimeCount;
}

View File

@@ -0,0 +1,51 @@
package jnpf.attendance.fallback;
import jnpf.attendance.AttendanceApi;
import jnpf.model.attendance.vo.attendance.AttendanceToThousandsFacesVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
/**
* describe
*
* @author HuangLinPan
* @date 2023/11/27
*/
@Slf4j
@Component
public class AttendanceApiFallback implements FallbackFactory<AttendanceApi> {
@Override
public AttendanceApi create(Throwable cause) {
cause.printStackTrace();
return new AttendanceApi() {
@Override
public Boolean invalidationCoupons(String tenantId) {
log.error("定时失效考勤劵失败...");
return Boolean.FALSE;
}
// @Override
// public Boolean overtimeVouchers(String tenantId) {
// log.error("定时发放加班劵失败...");
// return null;
// }
@Override
public Boolean storageRest(String tenantId) {
log.error("每月定时计算用户存休失败...");
return null;
}
@Override
public AttendanceToThousandsFacesVo attendanceToThousandsFaces() {
log.error("每月定时计算用户存休失败...");
return null;
}
};
}
}

View File

@@ -0,0 +1,37 @@
package jnpf.attendance.fallback;
import jnpf.attendance.AttendanceConfirmApi;
import jnpf.base.ActionResult;
import jnpf.model.thousandsfaces.TodayWorkVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
import java.util.List;
@Slf4j
@Component
public class AttendanceConfirmApiFallback implements FallbackFactory<AttendanceConfirmApi> {
@Override
public AttendanceConfirmApi create(Throwable cause) {
cause.printStackTrace();
return new AttendanceConfirmApi() {
@Override
public ActionResult<Boolean> autoCreateConfirm() {
return null;
}
@Override
public ActionResult<Boolean> confirmAutoSlippage() {
return null;
}
@Override
public List<TodayWorkVo> getTodayWorkConfirmList() {
return List.of();
}
};
}
}

View File

@@ -0,0 +1,53 @@
package jnpf.attendance.fallback;
import jnpf.attendance.AttendanceDailyRuleApi;
import jnpf.base.ActionResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
/**
* 获取用户信息Api降级处理
*
* @author JNPF开发平台组
* @version V3.1.0
* @copyright 引迈信息技术有限公司https://www.jnpfsoft.com
* @date 2021-03-24
*/
@Component
@Slf4j
public class AttendanceDailyRuleApiFallback implements FallbackFactory<AttendanceDailyRuleApi> {
@Override
public AttendanceDailyRuleApi create(Throwable cause) {
cause.printStackTrace();
return new AttendanceDailyRuleApi() {
@Override
public ActionResult initFixedScheduleRule(String tenantId) {
return ActionResult.fail("请求失败");
}
@Override
public ActionResult autoGrantBalance(String tenantId) {
return ActionResult.fail("请求失败");
}
@Override
public ActionResult<Boolean> userIsScheduling(String tenantId, String userId) {
return ActionResult.fail("请求失败");
}
@Override
public ActionResult<List<String>> userIsSchedulingOrdinary(List<String> organizeId) {
return ActionResult.fail("请求失败");
}
@Override
public ActionResult<Boolean> hasRuleByUserIdAndTime(String userId, Date start, Date end) {
return ActionResult.fail("请求失败");
}
};
}
}

View File

@@ -0,0 +1,62 @@
package jnpf.attendance.fallback;
import jnpf.attendance.AttendanceGroupApi;
import jnpf.attendance.dto.AttendanceUserGroupVo;
import jnpf.attendance.dto.AttendanceUserListGroupVO;
import jnpf.base.ActionResult;
import jnpf.entity.AttendanceGroup;
import jnpf.model.attendance.vo.AttendanceGroupVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
/**
* @Title:
* @Author: peng.hao
* @create: 2024/4/23:16:09
*/
@Slf4j
@Component
public class AttendanceGroupApiFallback implements FallbackFactory<AttendanceGroupApi> {
@Override
public AttendanceGroupApi create(Throwable cause) {
cause.printStackTrace();
return new AttendanceGroupApi() {
@Override
public AttendanceGroup queryTheNameOfTheAttendanceGroup(String groupId) {
return new AttendanceGroup();
}
@Override
public List<AttendanceUserGroupVo> getAttendanceUserGroup(List<String> userIds) {
log.error("AttendanceGroupApiFallback调用getAttendanceUserGroup失败");
return new ArrayList<>();
}
@Override
public List<AttendanceGroup> getGroupListByOrgId(String organizeId) {
return null;
}
@Override
public ActionResult<List<AttendanceUserListGroupVO>> getAttendanceUserListGroupVO(List<String> userIds) {
return null;
}
@Override
public ActionResult<AttendanceGroupVo> getAttendanceGroupByName(String organizeName, String groupName) {
return null;
}
@Override
public boolean checkScheduling() {
return false;
}
};
}
}

View File

@@ -0,0 +1,31 @@
package jnpf.attendance.fallback;
import jnpf.attendance.AttendanceApi;
import jnpf.attendance.AttendanceLineSchedulingConfigApi;
import jnpf.model.attendance.vo.attendance.AttendanceToThousandsFacesVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
/**
* describe
*
* @author HuangLinPan
* @date 2023/11/27
*/
@Slf4j
@Component
public class AttendanceLineSchedulingConfigApiFallback implements FallbackFactory<AttendanceLineSchedulingConfigApi> {
@Override
public AttendanceLineSchedulingConfigApi create(Throwable cause) {
cause.printStackTrace();
return new AttendanceLineSchedulingConfigApi() {
@Override
public Boolean noticeLineScheduling(String tenantId) {
return null;
}
};
}
}

View File

@@ -0,0 +1,30 @@
package jnpf.attendance.fallback;
import jnpf.attendance.AttendanceSimulateDataApi;
import jnpf.attendance.FtbClockInApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
/**
* 打卡api fallback
*
* @author yanwenfu
* @create 2023-12-04
*/
@Slf4j
@Component
public class AttendanceSimulateDataApiFallback implements FallbackFactory<AttendanceSimulateDataApi> {
@Override
public AttendanceSimulateDataApi create(Throwable cause) {
cause.printStackTrace();
return new AttendanceSimulateDataApi() {
@Override
public void clockIn(String tenantId) throws Exception {
log.error("调用模拟打卡失败...");
}
};
}
}

View File

@@ -0,0 +1,38 @@
package jnpf.attendance.fallback;
import jnpf.attendance.AttendanceUserApi;
import jnpf.attendance.dto.GroupUpdateByUserDTO;
import jnpf.base.ActionResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
/**
* describe
*
* @author HuangLinPan
* @date 2023/11/27
*/
@Slf4j
@Component
public class AttendanceUserApiFallback implements FallbackFactory<AttendanceUserApi> {
@Override
public AttendanceUserApi create(Throwable cause) {
cause.printStackTrace();
return new AttendanceUserApi() {
@Override
public ActionResult groupUpdateByPersonnel(GroupUpdateByUserDTO groupUpdateByUserDTO) {
log.error("定时失效考勤劵失败...");
return null;
}
@Override
public ActionResult<Boolean> userGroupUpdateBySecondNotice(String tenantId) {
return null;
}
};
}
}

View File

@@ -0,0 +1,60 @@
package jnpf.attendance.fallback;
import jnpf.attendance.FtbClockInApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
/**
* 打卡api fallback
*
* @author yanwenfu
* @create 2023-12-04
*/
@Slf4j
@Component
public class FtbClockInApiFallback implements FallbackFactory<FtbClockInApi> {
@Override
public FtbClockInApi create(Throwable cause) {
cause.printStackTrace();
return new FtbClockInApi() {
@Override
public Boolean dailyRuleChangeExecute() {
log.error("dailyRuleChangeExecute调用失败...");
return Boolean.FALSE;
}
@Override
public Boolean generateFtbAbsenceRecord(String tenantId) {
log.error("generateFtbAbsenceRecord调用失败...");
return Boolean.FALSE;
}
@Override
public Boolean generateAbsenceTask(String tenantId) {
log.error("generateAbsenceTask调用失败...");
return Boolean.FALSE;
}
@Override
public Boolean generateBeforeWorkRemind(String tenantId) {
log.error("generateBeforeWorkRemind调用失败...");
return false;
}
@Override
public Boolean generateRepairNum(String tenantId) {
log.error("生成补卡次数失败...");
return Boolean.FALSE;
}
@Override
public Boolean continuousCheck(String tenantId) {
log.error("判定连续动作失败...");
return Boolean.FALSE;
}
};
}
}

View File

@@ -0,0 +1,129 @@
package jnpf.attendance.fallback;
import jnpf.attendance.FtbStatisticsApi;
import jnpf.attendance.dto.*;
import jnpf.base.ActionResult;
import jnpf.model.attendance.dto.DayStatisticsDto;
import jnpf.model.attendance.dto.SalaryAttendanceSupportDto;
import jnpf.model.attendance.vo.attendance.AttendanceCustomizeTableVo;
import jnpf.model.attendance.vo.attendance.DayStatisticsPageListVo;
import jnpf.model.attendance.vo.attendance.DayStatisticsVo;
import jnpf.model.attendance.vo.attendance.SalaryAttendanceSupportVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Slf4j
@Component
public class FtbStatisticsApiFallback implements FallbackFactory<FtbStatisticsApi> {
@Override
public FtbStatisticsApi create(Throwable cause) {
// 打印降级原因
log.error("进入 FtbStatisticsApi 的 fallback降级原因", cause);
return new FtbStatisticsApi() {
@Override
public ActionResult<Boolean> userDayStatisticsInit(String tenantId) {
return ActionResult.success(Boolean.FALSE);
}
@Override
public ActionResult<Boolean> dayStatisticsNotice(String tenantId) {
return ActionResult.success(Boolean.FALSE);
}
@Override
public ActionResult<Boolean> monthStatisticsNotice(String tenantId) {
return ActionResult.success(Boolean.FALSE);
}
@Override
public ActionResult<Boolean> teamMonthStatisticsNotice(String tenantId) {
return ActionResult.success(Boolean.FALSE);
}
@Override
public void consentUnscheduledNotice(String tenantId) {
}
@Override
public ActionResult<Boolean> autoSealTimer(String tenantId) {
return ActionResult.success(Boolean.FALSE);
}
@Override
public List<AttendanceCountAvgHoursVo> countAttendanceAvgHours(AttendanceCountAvgHoursDto dto) {
return List.of();
}
@Override
public ActionResult<MonthStatsDetailsVo> getAttendanceAvgHoursDetails(MonthStatsDetailsDto dto) {
return ActionResult.success(null);
}
@Override
public ActionResult<List<MonthStatsPerCapitaVo>> getAttendanceMonthPerCapita(MonthStatsDetailsDto dto) {
return ActionResult.success(List.of());
}
@Override
public ActionResult<List<MonthStatsDailySituationVo>> getAttendanceDailySituation(MonthStatsDetailsDto dto) {
return ActionResult.success(List.of());
}
@Override
public ActionResult<List<MonthStatsHoursRankingVo>> getAttendanceHoursRanking(MonthStatsDetailsDto dto) {
return ActionResult.success(List.of());
}
@Override
public ActionResult<List<MonthStatsFullSituationVo>> getAttendanceFullSituation(MonthStatsDetailsDto dto) {
return ActionResult.success(List.of());
}
@Override
public ActionResult<MonthStatsAbnormalConditionVo> getAttendanceAbnormalCondition(MonthStatsDetailsDto dto) {
return ActionResult.success(null);
}
@Override
public ActionResult<List<MonthStatsOvertimeSituationVo>> getAttendanceOvertimeSituation(MonthStatsDetailsDto dto) {
return ActionResult.success(List.of());
}
@Override
public Map<String, SalaryAttendanceSupportVo> salaryAttendanceSupport(SalaryAttendanceSupportDto dto) {
return Map.of();
}
@Override
public List<AttendanceCustomizeTableVo> attendanceDayStaTable() {
return List.of();
}
@Override
public List<DayStatisticsPageListVo> attendanceDayStaList(SalaryAttendanceSupportDto dto) {
return List.of();
}
@Override
public List<DayStatisticsVo> getAttendanceDayStaList(DayStatisticsDto dto) {
return List.of();
}
@Override
public Map<String, List<DateDimensionsRangeVo>> getDimensionsAttendanceCountMap(DimensionsAttendanceCountDto dto) {
return Map.of();
}
@Override
public Map<String, Map<Date, Integer>> getDimensionsAttendanceDayCountMap(DimensionsAttendanceDayCountDto dto) {
return Map.of();
}
};
}
}

View File

@@ -0,0 +1,226 @@
package jnpf.authority;
import io.swagger.v3.oas.annotations.Operation;
import jnpf.authority.fallback.FtbAuthorityApiFallback;
import jnpf.base.ActionResult;
import jnpf.base.vo.PageListVO;
import jnpf.model.authority.dto.menu.FunctionMenuRemoteDTO;
import jnpf.model.authority.dto.menu.FuntionMenuDTO;
import jnpf.model.authority.dto.permission.OrganizeWithPositionsDTO;
import jnpf.model.authority.dto.role.FtbPermissionRoleInfoDTO;
import jnpf.model.authority.vo.person.FtbRoleListDropDownVO;
import jnpf.model.authority.vo.role.FtbPermissionRoleIdentificationVO;
import jnpf.model.authority.vo.role.FtbPermissionRoleInfoVO;
import jnpf.model.cultivate.CultivatePage;
import jnpf.model.cultivate.vo.common.InnerPowerPositionVO;
import jnpf.model.cultivate.vo.common.InnerPowerUserVO;
import jnpf.model.login.MenuTreeVO;
import jnpf.permission.dto.v2.user.QueryPageUserDTO;
import jnpf.permission.dto.v2.user.QueryPageUserMoreKeywordDTO;
import jnpf.permission.eum.v2.OrganizeCategoryEnums;
import jnpf.permission.eum.v2.UserWorkStatusEnums;
import jnpf.permission.vo.organize.OrganizeAndPositionListVO;
import jnpf.permission.vo.store.StoreBaseListInfo;
import jnpf.permission.vo.v2.TargetAuthIdsVO;
import jnpf.permission.vo.v2.organzie.OrganizeGeneralDetailVO;
import jnpf.permission.vo.v2.organzie.OrganizeManagerFilterNodeVO;
import jnpf.permission.vo.v2.organzie.OrganizeManagerNodeVO;
import jnpf.permission.vo.v2.position.PositionListUserVO;
import jnpf.permission.vo.v2.user.UserBoundVO;
import jnpf.util.NoDataSourceBind;
import lombok.SneakyThrows;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.cloud.openfeign.SpringQueryMap;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
/**
* @Author: peng.hao
* @create: 2025/3/27
*/
@FeignClient(name = "jnpf-ftb", fallbackFactory = FtbAuthorityApiFallback.class)
public interface FtbAuthorityApi {
/**
* 获取当前人员的数据权限范围
*
* @return
*/
@GetMapping("/web/permission-role/query-user-scope-permission")
Map<String, String> queryUserScopeOfPermission(@RequestParam("userId") String userId);
@Operation(summary = "[门店基础信息列表auth api] 根据登录人权限得到权限范围内门店基础信息")
@GetMapping(value = "/permission/organize/list/store/login")
List<StoreBaseListInfo> authStoreBaseListInfo();
@Operation(summary = "[列表] 指定组织下得所有员工信息(FTB带权限)")
@GetMapping("/permission/users/list/targetOrganize/auth/api")
List<UserBoundVO> listTargetOrganizeIdAuthApi(@RequestParam(value = "organizeId") String organizeId, @RequestParam(value = "userWorkStatusEnumsList", required = false) List<UserWorkStatusEnums> userWorkStatusEnumsList);
@Operation(summary = "[列表] 指定组织集合下得所有员工信息(FTB带权限)")
@PostMapping("/permission/users/list/targetOrganizeIds/auth/api")
List<UserBoundVO> listTargetOrganizeIdsAuthApi(@RequestBody List<String> organizeIds, @RequestParam(value = "userWorkStatusEnumsList", required = false) List<UserWorkStatusEnums> userWorkStatusEnumsList);
@Operation(summary = "[分页] 在职人员列表")
@PostMapping("/permission/users/page")
@NoDataSourceBind
ActionResult<PageListVO<UserBoundVO>> pagePost(@RequestBody QueryPageUserDTO dto);
@Operation(summary = "[分页] 在职人员列表POST更多关键字信息")
@PostMapping("/permission/page/moreKeyword")
@NoDataSourceBind
ActionResult<PageListVO<UserBoundVO>> pagePostMoreKeyword(@RequestBody QueryPageUserMoreKeywordDTO dto);
@Operation(summary = "[列表]人员权限过滤后的岗位用户列表")
@GetMapping("/permission/position/tree/users")
ActionResult<List<PositionListUserVO>> authListPositionTreeUser();
@Operation(summary = "[api列表]权限范围内的多个组织及其岗位列表(不查人)")
@PostMapping("/permission/position/api/list/auth/organize-with-positions")
List<OrganizeAndPositionListVO> authOrganizeWithPositions(@RequestBody OrganizeWithPositionsDTO dto);
@Operation(summary = "[列表]权限过滤,获取所有用户信息,含绑定关系,或指定用户. 不使用权限则返回全部")
@PostMapping("/permission/users/info/all/auth")
@NoDataSourceBind
ActionResult<List<UserBoundVO>> authGetAllUserInfoBatch();
@Operation(summary = "[列表]权限范围内仅返回用户 id 列表,不查关系与 VO")
@PostMapping("/permission/users/ids/auth")
@NoDataSourceBind
ActionResult<List<String>> authGetPermissionScopeUserIds();
@Operation(summary = "[树形]人员权限过滤后的组织(公司,部门,门店,班主),人员")
@GetMapping(value = "/permission/organize/tree/users")
ActionResult<List<OrganizeManagerNodeVO>> listOrganizeTreeUsers();
@Operation(summary = "[列表]人员权限过滤后的组织列表")
@GetMapping(value = "/permission/organize/info/list/users")
@NoDataSourceBind
ActionResult<List<OrganizeGeneralDetailVO>> authOrganizesByUserBound(@RequestParam(value = "organizeCategoryEnums", required = false) List<OrganizeCategoryEnums> organizeCategoryEnums);
/**
* @param organizeCategoryEnums 组织类型
* @param workStatusEnums 工作状态
* @param withEmployee 是否包含人员
* @param filterBindOtherStore 过滤绑定第三方信息门店
* @param filterBindPayStore 过滤收银平台门店
* @return 组织树(with auth)
*/
@Operation(summary = "[api树形,滤掉没有的分支]人员权限过滤后的组织(公司,部门,门店,班主),默认不带人员")
@GetMapping(value = "/permission/organize/api/tree/users/filterNode")
List<OrganizeManagerFilterNodeVO> listOrganizeTreeFilterNode(
@RequestParam(value = "organizeCategoryEnums", required = false) List<OrganizeCategoryEnums> organizeCategoryEnums,
@RequestParam(value = "workStatusEnums", required = false) List<UserWorkStatusEnums> workStatusEnums,
@RequestParam(value = "withEmployee", required = false) Boolean withEmployee,
@RequestParam(value = "filterBindOtherStore", required = false) Boolean filterBindOtherStore,
@RequestParam(value = "filterBindPayStore", required = false) Boolean filterBindPayStore
);
@Operation(summary = "角色列表下拉")
@GetMapping(value = "/web/permission-role-authorize-person/allRolesOfTheCurrentPerson")
@NoDataSourceBind
ActionResult<List<FtbRoleListDropDownVO>> roleListDropDown(@RequestParam("userId") String userId, @RequestParam("tenantId") String tenantId);
/**
* 根据模块编码获取当前人员的数据权限范围
*
* @return
*/
@GetMapping("/web/permission-role/query-user-scope-permission-for-module-code")
InnerPowerUserVO queryUserScopeOfPermissionForModuleCode();
/**
* 远程client
* 包含新增修改
*/
@SneakyThrows
@PostMapping("/remoteClient")
@NoDataSourceBind
void remoteClient(FunctionMenuRemoteDTO dto);
@GetMapping("/position/get-curr-login-user-has-permission-position-id")
InnerPowerPositionVO getCurrLoginUserHasPermissionPositionId(@RequestParam(name = "permissionModule", defaultValue = "") String permissionModule);
/**
* 更具岗位id清除所有绑定的角色
*/
@PostMapping("/web/permission-role-authorize-post/clearRoleByPostId")
void clearRoleByPostId(@RequestBody List<String> postIds);
/**
* @param userIds 用户列表
* @param status 状态 1禁用 0启用 -1-所有
* @param tenantId 租户id
* @return
*/
@Operation(summary = "[列表]根据用户列表批量查询权限范围的门店")
@PostMapping(value = "/permission/organize/batchForUserIds/{status}/{moduleId}/{tenantId}")
@NoDataSourceBind
Map<String, List<String>> batchAuthOrganizesForUserIdsAndTenantId(@RequestBody List<String> userIds, @PathVariable("status") Integer status,@PathVariable("moduleId") String moduleId,@PathVariable("tenantId") String tenantId);
/**
* @param userIds 用户列表
* @param status 状态 1禁用 0启用 -1-所有
* @param tenantId 租户id
* @return
*/
@Operation(summary = "[列表]根据用户列表批量查询权限范围的门店")
@PostMapping(value = "/permission/organize/batchAllForUserIds/{status}/{moduleId}/{tenantId}")
@NoDataSourceBind
Map<String, List<String>> batchAuthOrganizesAllForUserIdsAndTenantId(@RequestBody List<String> userIds, @PathVariable("status") Integer status,@PathVariable("moduleId") String moduleId,@PathVariable("tenantId") String tenantId);
/**
* @param userIds 用户列表
* @param status 状态 1禁用 0启用 -1-所有
* @return
*/
@Operation(summary = "[列表]根据用户列表批量查询权限范围的门店")
@PostMapping(value = "/permission/organize/batchForUserIds/{status}")
Map<String, List<String>> batchAuthOrganizesForUserIds(@RequestBody List<String> userIds, @PathVariable("status") Integer status);
/**
* 角色列表
*
* @return {@link ActionResult }<{@link PageListVO }<{@link FtbPermissionRoleInfoVO }>>
*/
@GetMapping("/web/permission-role/role-list")
ActionResult<PageListVO<FtbPermissionRoleInfoVO>> permissionList(@SpringQueryMap CultivatePage cultivatePage, @SpringQueryMap FtbPermissionRoleInfoDTO roleInfoDTO);
/**
* 当前登录用户所有权限用户id
*
* @return 用户id集合
*/
@GetMapping("/web/permission-role-authorize-person/permission-user")
ActionResult<List<String>> permissionUser(@RequestParam("userId") String userId, @RequestParam("permissionModule") String permissionModule, @RequestParam("category") String category);
/**
* 员工已有的功能权限标识集合
*/
@GetMapping("/web/permission-role/permission-identification-collection")
ActionResult<FtbPermissionRoleIdentificationVO> permissionIdentificationCollection();
/**
* 查询那些人员具有当前按钮权限
*/
@PostMapping("/web/permission-role-authorize-person/queryButtonPermission")
List<String> queryButtonPermission(@RequestBody FuntionMenuDTO funtion);
/**
* 根据用户Id获取用户权限的用户Id集合超级管理员不要调用此方法
* @return 用户id->所具有的权限用户id集合
*/
@PostMapping("/web/permission-role-authorize-person/collection-of-user")
Map<String,List<String>> getUserPermissionUserCollection(@RequestBody List<String> userIds);
@GetMapping(value = "/permission/organize/user-auth")
TargetAuthIdsVO getUserAuth();
/**
* 当前登录用户菜单树(与 FTB 登录菜单一致type=Web|App
*/
@GetMapping("/web/permission-role/obtain-menus-on-token")
ActionResult<List<MenuTreeVO>> obtainMenusOnToken(@RequestParam(value = "type", defaultValue = "Web") String type);
}

View File

@@ -0,0 +1,188 @@
package jnpf.authority.fallback;
import jnpf.authority.FtbAuthorityApi;
import jnpf.base.ActionResult;
import jnpf.base.vo.PageListVO;
import jnpf.model.authority.dto.menu.FunctionMenuRemoteDTO;
import jnpf.model.authority.dto.menu.FuntionMenuDTO;
import jnpf.model.authority.dto.permission.OrganizeWithPositionsDTO;
import jnpf.model.authority.dto.role.FtbPermissionRoleInfoDTO;
import jnpf.model.authority.vo.person.FtbRoleListDropDownVO;
import jnpf.model.authority.vo.role.FtbPermissionRoleIdentificationVO;
import jnpf.model.authority.vo.role.FtbPermissionRoleInfoVO;
import jnpf.model.cultivate.CultivatePage;
import jnpf.model.cultivate.vo.common.InnerPowerPositionVO;
import jnpf.model.cultivate.vo.common.InnerPowerUserVO;
import jnpf.model.login.MenuTreeVO;
import jnpf.permission.dto.v2.user.QueryPageUserDTO;
import jnpf.permission.dto.v2.user.QueryPageUserMoreKeywordDTO;
import jnpf.permission.eum.v2.OrganizeCategoryEnums;
import jnpf.permission.eum.v2.UserWorkStatusEnums;
import jnpf.permission.vo.organize.OrganizeAndPositionListVO;
import jnpf.permission.vo.store.StoreBaseListInfo;
import jnpf.permission.vo.v2.TargetAuthIdsVO;
import jnpf.permission.vo.v2.organzie.OrganizeGeneralDetailVO;
import jnpf.permission.vo.v2.organzie.OrganizeManagerFilterNodeVO;
import jnpf.permission.vo.v2.organzie.OrganizeManagerNodeVO;
import jnpf.permission.vo.v2.position.PositionListUserVO;
import jnpf.permission.vo.v2.user.UserBoundVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@Slf4j
@Component
public class FtbAuthorityApiFallback implements FallbackFactory<FtbAuthorityApi> {
@Override
public FtbAuthorityApi create(Throwable cause) {
cause.printStackTrace();
return new FtbAuthorityApi() {
@Override
public Map<String, String> queryUserScopeOfPermission(String userId) {
log.error("queryUserScopeOfPermission 调用失败...");
return null;
}
@Override
public List<StoreBaseListInfo> authStoreBaseListInfo() {
return List.of();
}
@Override
public List<UserBoundVO> listTargetOrganizeIdAuthApi(String organizeId, List<UserWorkStatusEnums> userWorkStatusEnumsList) {
return List.of();
}
@Override
public List<UserBoundVO> listTargetOrganizeIdsAuthApi(List<String> organizeIds, List<UserWorkStatusEnums> userWorkStatusEnumsList) {
return List.of();
}
@Override
public ActionResult<PageListVO<UserBoundVO>> pagePost(QueryPageUserDTO dto) {
return null;
}
@Override
public ActionResult<PageListVO<UserBoundVO>> pagePostMoreKeyword(QueryPageUserMoreKeywordDTO dto) {
return null;
}
@Override
public ActionResult<List<PositionListUserVO>> authListPositionTreeUser() {
return null;
}
@Override
public List<OrganizeAndPositionListVO> authOrganizeWithPositions(OrganizeWithPositionsDTO dto) {
return List.of();
}
@Override
public ActionResult<List<UserBoundVO>> authGetAllUserInfoBatch() {
return null;
}
@Override
public ActionResult<List<String>> authGetPermissionScopeUserIds() {
return null;
}
@Override
public ActionResult<List<OrganizeManagerNodeVO>> listOrganizeTreeUsers() {
return null;
}
@Override
public ActionResult<List<OrganizeGeneralDetailVO>> authOrganizesByUserBound(List<OrganizeCategoryEnums> organizeCategoryEnums) {
return null;
}
@Override
public List<OrganizeManagerFilterNodeVO> listOrganizeTreeFilterNode(List<OrganizeCategoryEnums> organizeCategoryEnums, List<UserWorkStatusEnums> workStatusEnums, Boolean withEmployee, Boolean filterBindOtherStore, Boolean filterBindPayStore) {
return List.of();
}
@Override
public ActionResult<List<FtbRoleListDropDownVO>> roleListDropDown(String userId, String tenantId) {
return null;
}
@Override
public InnerPowerUserVO queryUserScopeOfPermissionForModuleCode() {
return null;
}
@Override
public void remoteClient(FunctionMenuRemoteDTO dto) {
}
@Override
public InnerPowerPositionVO getCurrLoginUserHasPermissionPositionId(String permissionModule) {
return null;
}
@Override
public void clearRoleByPostId(List<String> postIds) {
}
@Override
public Map<String, List<String>> batchAuthOrganizesForUserIdsAndTenantId(List<String> userIds, Integer status, String moduleId, String tenantId) {
return Map.of();
}
@Override
public Map<String, List<String>> batchAuthOrganizesAllForUserIdsAndTenantId(List<String> userIds, Integer status, String moduleId, String tenantId) {
return Map.of();
}
@Override
public Map<String, List<String>> batchAuthOrganizesForUserIds(List<String> userIds, Integer status) {
return null;
}
@Override
public ActionResult<PageListVO<FtbPermissionRoleInfoVO>> permissionList(CultivatePage cultivatePage, FtbPermissionRoleInfoDTO roleInfoDTO) {
return null;
}
@Override
public ActionResult<List<String>> permissionUser(String userId, String permissionModule, String category) {
return null;
}
@Override
public ActionResult<FtbPermissionRoleIdentificationVO> permissionIdentificationCollection() {
return null;
}
@Override
public List<String> queryButtonPermission(FuntionMenuDTO funtion) {
return null;
}
@Override
public Map<String, List<String>> getUserPermissionUserCollection(List<String> userIds) {
return Collections.emptyMap();
}
@Override
public ActionResult<List<MenuTreeVO>> obtainMenusOnToken(String type) {
log.warn("FtbAuthorityApi fallback: obtainMenusOnToken type={}", type);
return ActionResult.success(Collections.emptyList());
}
@Override
public TargetAuthIdsVO getUserAuth() {
return null;
}
};
}
}

View File

@@ -0,0 +1,57 @@
package jnpf.certificate;
import jnpf.base.ActionResult;
import jnpf.certificate.fallback.CertificateManageFallbackApi;
import jnpf.model.certificate.vo.CertificateOrganizeBusinessLicenseVO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import javax.validation.Valid;
import java.util.Collection;
import java.util.List;
@FeignClient(name = "jnpf-ftb", fallback = CertificateManageFallbackApi.class, path = "/web/certificate-manage-api")
public interface CertificateManageApi {
/**
* 根据组织ID查询营业执照信息。
*
* @param organizeId 组织ID
* @return 营业执照信息
*/
@GetMapping("/query-business-license")
ActionResult<CertificateOrganizeBusinessLicenseVO> queryBusinessLicense(@RequestParam("organizeId") String organizeId);
/**
* 根据组织ID列表批量查询营业执照信息。
*
* @param organizeIds 组织ID列表
* @return 营业执照信息列表
*/
@PostMapping("/query-business-license-batch")
ActionResult<List<CertificateOrganizeBusinessLicenseVO>> queryBusinessLicenseBatch(@RequestBody Collection<String> organizeIds);
/**
* 保存组织营业执照信息。
*
* @param req 营业执照保存参数
* @return 操作结果
*/
@PostMapping("/save-business-license")
ActionResult<Void> saveBusinessLicense(@Valid @RequestBody CertificateOrganizeBusinessLicenseVO req);
/**
* 根据组织ID删除该主体下全部证照信息。
*
* @param organizeId 组织ID
* @param loginUserId 登录用户ID
* @return 操作结果
*/
@DeleteMapping("/delete-business-license")
ActionResult<Void> deleteBusinessLicense(@RequestParam("organizeId") String organizeId,
@RequestParam(value = "loginUserId", required = false) String loginUserId);
}

View File

@@ -0,0 +1,19 @@
package jnpf.certificate;
import jnpf.base.ActionResult;
import jnpf.certificate.fallback.CertificateWarningFallbackApi;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(name = "jnpf-ftb", fallback = CertificateWarningFallbackApi.class, path = "/web/certificate-warning-api")
public interface CertificateWarningApi {
/**
* 检查并发送预警
* @param tenantId
* @return
*/
@PostMapping("/checkAndSendCertificateWarning")
ActionResult<Boolean> checkAndSendCertificateWarning(@RequestParam("tenantId") String tenantId);
}

View File

@@ -0,0 +1,44 @@
package jnpf.certificate.fallback;
import jnpf.base.ActionResult;
import jnpf.certificate.CertificateManageApi;
import jnpf.model.certificate.vo.CertificateOrganizeBusinessLicenseVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
* 组织营业执照接口降级实现。
*/
@Slf4j
@Component
public class CertificateManageFallbackApi implements CertificateManageApi {
@Override
public ActionResult<CertificateOrganizeBusinessLicenseVO> queryBusinessLicense(String organizeId) {
log.error("queryBusinessLicense调用失败organizeId={}", organizeId);
return ActionResult.success(null);
}
@Override
public ActionResult<List<CertificateOrganizeBusinessLicenseVO>> queryBusinessLicenseBatch(Collection<String> organizeIds) {
log.error("queryBusinessLicenseBatch调用失败organizeIds={}", organizeIds);
return ActionResult.success(Collections.emptyList());
}
@Override
public ActionResult<Void> saveBusinessLicense(CertificateOrganizeBusinessLicenseVO req) {
log.error("saveBusinessLicense调用失败req={}", req);
return ActionResult.success();
}
@Override
public ActionResult<Void> deleteBusinessLicense(String organizeId, String loginUserId) {
log.error("deleteBusinessLicense failed, organizeId={}.loginUserId={}", organizeId,loginUserId);
return ActionResult.success();
}
}

View File

@@ -0,0 +1,16 @@
package jnpf.certificate.fallback;
import jnpf.base.ActionResult;
import jnpf.certificate.CertificateWarningApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class CertificateWarningFallbackApi implements CertificateWarningApi {
@Override
public ActionResult<Boolean> checkAndSendCertificateWarning(String tenantId) {
log.error("checkAndSendCertificateWarning调用失败tenantId={}", tenantId);
return ActionResult.success(Boolean.FALSE);
}
}

View File

@@ -0,0 +1,33 @@
package jnpf.cultivate;
import jnpf.cultivate.fallback.FtbCultivateIdentifyApiFallback;
import jnpf.util.NoDataSourceBind;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
* 鉴定api
*/
@FeignClient(name = "jnpf-ftb", fallbackFactory = FtbCultivateIdentifyApiFallback.class, path = "/cultivate")
public interface FtbCultivateIdentifyApi {
/**
* 处理鉴定逾期数据
*
* @param tenantId
* @return
*/
@PostMapping(value = "/apply/setIdentifyBeOverdue")
@NoDataSourceBind
Boolean setIdentifyBeOverdue(@RequestParam(value = "tenantId") String tenantId);
/**
* 计划鉴定时间提醒
*
* @param tenantId
* @return
*/
@PostMapping(value = "/apply/setIdentifyRemind")
@NoDataSourceBind
Boolean setIdentifyRemind(@RequestParam(value = "tenantId") String tenantId);
}

View File

@@ -0,0 +1,33 @@
package jnpf.cultivate;
import jnpf.cultivate.fallback.FtbCultivateLearnTaskApiFallback;
import jnpf.util.NoDataSourceBind;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
/**
* 鉴定api
*/
@FeignClient(name = "jnpf-ftb", fallbackFactory = FtbCultivateLearnTaskApiFallback.class, path = "/web/learnTaskList/")
public interface FtbCultivateLearnTaskListApi {
/**
* 定时加入任务
*
* @return
*/
@GetMapping("/timing/timingAddNewPersonToTaskNew/{tenantId}")
@NoDataSourceBind
void timingAddNewPersonToTaskNew(@PathVariable("tenantId") String tenantId);
/**
* 定时提醒任务(每天定点)
*
* @return
*/
@GetMapping("/timing/timingTaskLearningAlertNew/{tenantId}")
@NoDataSourceBind
void timingTaskLearningAlertNew(@PathVariable("tenantId") String tenantId);
}

View File

@@ -0,0 +1,42 @@
package jnpf.cultivate;
import io.swagger.v3.oas.annotations.Operation;
import jnpf.base.ActionResult;
import jnpf.cultivate.fallback.FtbCultivatePromotionFallback;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
/**
* @Title:FtbCultivatePromotionMemberApi
* @Author:peng.hao
* @create: 2024/1/1815:58
*/
@FeignClient(name = "jnpf-ftb", fallbackFactory = FtbCultivatePromotionFallback.class )
public interface FtbCultivatePromotionApi {
/**
* 拖动删除成员启用对应晋升通道
* @param userIds 用户id
* @return
*/
@PutMapping("/cul_pro_member/deleteMembersToProChannel")
ActionResult<Boolean> deleteMembersToProChannel(@RequestBody List<String> userIds);
/**
* 获取是否有人岗位职等的晋升申请
* @param postId 公司岗位ID
* @param grandId 职等ID
* @param userId 用户ID
* @return 成功结果
*/
@GetMapping("/cul-post-apply/userIsHasApply")
@Operation(summary = "查看当前的人岗位职等是否存在晋升申请")
ActionResult<Boolean> isThereAnAppForThePosLevel(@RequestParam("postId") String postId,
@RequestParam("grandId") String grandId,
@RequestParam("userId") String userId);
}

View File

@@ -0,0 +1,101 @@
package jnpf.cultivate;
import jnpf.base.ActionResult;
import jnpf.cultivate.fallback.FtbCultivateStoreStatisticApiFallback;
import jnpf.model.cultivate.dto.storestatistics.*;
import jnpf.model.cultivate.vo.position.*;
import jnpf.model.thousandsfaces.TodayWorkVo;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.List;
/**
* 鉴定api
*/
@FeignClient(name = "jnpf-ftb", fallbackFactory = FtbCultivateStoreStatisticApiFallback.class, path = "/web/store-index-statistics")
public interface FtbCultivateStoreStatisticApi {
/**
* 店长页面 培训统计数量
*/
@PostMapping("/get-cultivate-count")
ActionResult<FtbCultivateStoreCountVO> getCultivateCount(@RequestBody FtbCultivateStoreStatisticsReq req);
/**
* 查询我的考试列表
*
* @param req
* @return
*/
@PostMapping("/queryMyExamList")
ActionResult<List<TodayWorkVo>> queryMyExamList(@RequestBody StoreStatisticsMyExamReq req);
/**
* 待我批阅(下属的)
*
* @param req
* @return
*/
@PostMapping("/queryWaitMyReadOver")
ActionResult<List<TodayWorkVo>> queryWaitMyReadOver(@RequestBody StoreStatisticsWaitMyCheckExamReq req);
/**
* 今日工作-待参与及参与中的线下培训<负责人及参与人均属于相关人员>列表
*
* @param req
* @return
*/
@PostMapping("/queryOfflineTrainList")
ActionResult<List<TodayWorkVo>> queryOfflineTrainList(@RequestBody StoreOfflineTrainReq req);
/**
* 今日工作-我的任务(当日开始的培训任务)列表
*
* @param req
* @return
*/
@PostMapping("/myTaskList")
ActionResult<List<TodayWorkVo>> storeMyTaskList(@RequestBody StoreOfflineTrainReq req);
/**
* 今日工作-鉴定他人(当日的待鉴定)列表
*
* @param req
* @return
*/
@PostMapping("/myIdentityList")
ActionResult<List<TodayWorkVo>> storeMyIdentityList(@RequestBody StoreIdentityReq req);
/**
* 员工界面 查询未学习的通用课程数量
*
* @param req
* @return
*/
@PostMapping("/get-worker-cultivate-count")
ActionResult<FtbCultivateWorkerCountVO> getWorkerCultivateCount(@RequestBody FtbCultivateStoreStatisticsReq req);
/**
* 工作台-员工
*/
@PostMapping("/person/training-statistics")
ActionResult<FtbPersonTrainingStatisticsVO> personTrainingStatistics(@RequestBody FtbCultivateStoreStatisticsReq req);
/**
* 工作台-店长
*/
@PostMapping("/store-manager/training-statistics")
ActionResult<FtbStoreManagerTrainingStatisticsVO> storeManagerTrainingStatistics(@RequestBody FtbCultivateStoreStatisticsReq req);
/**
* 工作台-管理层
*/
@PostMapping("/manager/training-statistics")
ActionResult<FtbManagerTrainingStatisticsVO> managerTrainingStatistics(@RequestBody FtbCultivateStoreStatisticsReq req);
}

View File

@@ -0,0 +1,51 @@
package jnpf.cultivate;
import jnpf.cultivate.fallback.FtbCultivateTeachingApiFallback;
import jnpf.model.cultivate.vo.teaching.MyPracticeSummaryVo;
import jnpf.model.cultivate.vo.teaching.SuperiorTeachingSummaryVo;
import jnpf.model.cultivate.vo.teaching.TeachingStoreCountVo;
import jnpf.model.cultivate.vo.teaching.TodaySummaryDataVo;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
* 带教api
*/
@FeignClient(name = "jnpf-ftb", fallbackFactory = FtbCultivateTeachingApiFallback.class, path = "/")
public interface FtbCultivateTeachingApi {
/**
* 店长界面我的带教统计
* @param storeId 门店id
* @return TeachingStoreCountVo
*/
@GetMapping("app/teachingRecord/storeTeachingCount")
TeachingStoreCountVo storeTeachingCount(@RequestParam("storeId") String storeId);
/**
* App店长界面-今日练习汇总数据
*
* @param storeId 查询参数
* @return 练习汇总数据
*/
@GetMapping("teachingRecord/app/getTodaySummary")
TodaySummaryDataVo getTodaySummary(@RequestParam("storeId") String storeId);
/**
* 员工界面-上级带教统计
* @param storeId 门店id
* @return TeachingStoreCountVo
*/
@GetMapping("app/teachingRecord/getSuperiorTeachingSummary")
SuperiorTeachingSummaryVo getSuperiorTeachingSummary(@RequestParam("storeId") String storeId);
/**
* 员工界面--我的练习汇总数据
*
* @param storeId 查询参数
* @return 练习汇总数据
*/
@GetMapping("teachingRecord/app/getMyPracticeSummary")
MyPracticeSummaryVo getMyPracticeSummary(@RequestParam("storeId") String storeId);
}

View File

@@ -0,0 +1,51 @@
package jnpf.cultivate;
import jnpf.base.ActionResult;
import jnpf.cultivate.fallback.V2CultivateOldDealApiFallback;
import jnpf.util.NoDataSourceBind;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(name = "jnpf-ftb", fallbackFactory = V2CultivateOldDealApiFallback.class, path = "/v2/cultivate/old")
public interface V2CultivateOldDealApi {
/**
* 课程心得评论旧数据处理
*
* @param tenantId 租户ID
* @return 响应
*/
@NoDataSourceBind
@GetMapping("/gained/comment")
ActionResult<Boolean> dealOldData(@RequestParam("tenantId") String tenantId);
@NoDataSourceBind
@GetMapping("/identify/deal-old")
ActionResult<Boolean> identifyDealOldData(@RequestParam("tenantId") String tenantId);
/**
* 迁移旧培训任务数据到新的任务日志表
*
* @param tenantId 租户ID
* @return 响应
*/
@NoDataSourceBind
@GetMapping("/task/old-data")
ActionResult<String> migrateOldTaskData(@RequestParam("tenantId") String tenantId);
/**
* 旧晋升通道成员数据迁移接口
* 将 ftb_cultivate_promotion_member_new 表中的用户数据迁移到
* ftb_cultivate_promotion_user 和 ftb_cultivate_promotion_setting 表中
* 同时校验用户是否为正常状态enabledMark = 1
*
* @param tenantId 租户ID
* @param promotionId 晋升通道ID可选如果传入则只迁移指定通道的数据
* @return 响应结果
*/
@NoDataSourceBind
@GetMapping("/promotion/migrate-old-data")
ActionResult<String> migratePromotionOldData(@RequestParam("tenantId") String tenantId,
@RequestParam(value = "promotionId", required = false) String promotionId);
}

View File

@@ -0,0 +1,29 @@
package jnpf.cultivate.fallback;
import jnpf.cultivate.FtbCultivateIdentifyApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class FtbCultivateIdentifyApiFallback implements FallbackFactory<FtbCultivateIdentifyApi> {
@Override
public FtbCultivateIdentifyApi create(Throwable cause) {
cause.printStackTrace();
return new FtbCultivateIdentifyApi() {
@Override
public Boolean setIdentifyBeOverdue(String tenantId) {
log.error("setIdentifyBeOverdue调用失败...");
return false;
}
@Override
public Boolean setIdentifyRemind(String tenantId) {
log.error("setIdentifyRemind调用失败...");
return false;
}
};
}
}

View File

@@ -0,0 +1,31 @@
package jnpf.cultivate.fallback;
import jnpf.cultivate.FtbCultivateLearnTaskListApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class FtbCultivateLearnTaskApiFallback implements FallbackFactory<FtbCultivateLearnTaskListApi> {
@Override
public FtbCultivateLearnTaskListApi create(Throwable cause) {
log.error("进入 FtbCultivateLearnTaskApiFallback 的 fallback降级原因", cause); // 打印降级原因
return new FtbCultivateLearnTaskListApi() {
@Override
public void timingAddNewPersonToTaskNew(String tenantId) {
}
@Override
public void timingTaskLearningAlertNew(String tenantId) {
}
};
}
}

View File

@@ -0,0 +1,34 @@
package jnpf.cultivate.fallback;
import jnpf.base.ActionResult;
import jnpf.cultivate.FtbCultivatePromotionApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
import java.util.List;
@Slf4j
@Component
public class FtbCultivatePromotionFallback implements FallbackFactory<FtbCultivatePromotionApi> {
@Override
public FtbCultivatePromotionApi create(Throwable cause) {
cause.printStackTrace();
return new FtbCultivatePromotionApi() {
@Override
public ActionResult<Boolean> deleteMembersToProChannel(List<String> userIds) {
log.error("deleteMembersToProChannel 调用失败...");
return null;
}
@Override
public ActionResult<Boolean> isThereAnAppForThePosLevel(String postId, String grandId, String userId) {
log.error("isThereAnAppForThePosLevel 调用失败...");
return null;
}
};
}
}

View File

@@ -0,0 +1,76 @@
package jnpf.cultivate.fallback;
import jnpf.base.ActionResult;
import jnpf.cultivate.FtbCultivateStoreStatisticApi;
import jnpf.model.cultivate.dto.storestatistics.*;
import jnpf.model.cultivate.vo.position.*;
import jnpf.model.thousandsfaces.TodayWorkVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
import java.util.List;
@Slf4j
@Component
public class FtbCultivateStoreStatisticApiFallback implements FallbackFactory<FtbCultivateStoreStatisticApi> {
@Override
public FtbCultivateStoreStatisticApi create(Throwable cause) {
log.error("进入 FtbCultivateStoreStatisticApi 的 fallback降级原因", cause); // 打印降级原因
return new FtbCultivateStoreStatisticApi() {
@Override
public ActionResult<FtbCultivateStoreCountVO> getCultivateCount(FtbCultivateStoreStatisticsReq req) {
return null;
}
@Override
public ActionResult<List<TodayWorkVo>> queryMyExamList(StoreStatisticsMyExamReq req) {
return null;
}
@Override
public ActionResult<List<TodayWorkVo>> queryWaitMyReadOver(StoreStatisticsWaitMyCheckExamReq req) {
return null;
}
@Override
public ActionResult<List<TodayWorkVo>> queryOfflineTrainList(StoreOfflineTrainReq req) {
return null;
}
@Override
public ActionResult<List<TodayWorkVo>> storeMyTaskList(StoreOfflineTrainReq req) {
return null;
}
@Override
public ActionResult<List<TodayWorkVo>> storeMyIdentityList(StoreIdentityReq req) {
return null;
}
@Override
public ActionResult<FtbCultivateWorkerCountVO> getWorkerCultivateCount(FtbCultivateStoreStatisticsReq req) {
return null;
}
@Override
public ActionResult<FtbPersonTrainingStatisticsVO> personTrainingStatistics(FtbCultivateStoreStatisticsReq req) {
return null;
}
@Override
public ActionResult<FtbStoreManagerTrainingStatisticsVO> storeManagerTrainingStatistics(FtbCultivateStoreStatisticsReq req) {
return null;
}
@Override
public ActionResult<FtbManagerTrainingStatisticsVO> managerTrainingStatistics(FtbCultivateStoreStatisticsReq req) {
return null;
}
};
}
}

View File

@@ -0,0 +1,42 @@
package jnpf.cultivate.fallback;
import jnpf.cultivate.FtbCultivateTeachingApi;
import jnpf.model.cultivate.vo.teaching.MyPracticeSummaryVo;
import jnpf.model.cultivate.vo.teaching.SuperiorTeachingSummaryVo;
import jnpf.model.cultivate.vo.teaching.TeachingStoreCountVo;
import jnpf.model.cultivate.vo.teaching.TodaySummaryDataVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class FtbCultivateTeachingApiFallback implements FallbackFactory<FtbCultivateTeachingApi> {
@Override
public FtbCultivateTeachingApi create(Throwable cause) {
cause.printStackTrace();
return new FtbCultivateTeachingApi() {
@Override
public TeachingStoreCountVo storeTeachingCount(String storeId) {
return null;
}
@Override
public TodaySummaryDataVo getTodaySummary(String storeId) {
return new TodaySummaryDataVo();
}
@Override
public SuperiorTeachingSummaryVo getSuperiorTeachingSummary(String storeId) {
return null;
}
@Override
public MyPracticeSummaryVo getMyPracticeSummary(String storeId) {
return null;
}
};
}
}

View File

@@ -0,0 +1,39 @@
package jnpf.cultivate.fallback;
import jnpf.base.ActionResult;
import jnpf.cultivate.V2CultivateOldDealApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class V2CultivateOldDealApiFallback implements FallbackFactory<V2CultivateOldDealApi> {
@Override
public V2CultivateOldDealApi create(Throwable cause) {
cause.printStackTrace();
return new V2CultivateOldDealApi() {
@Override
public ActionResult<Boolean> dealOldData(String tenantId) {
return null;
}
@Override
public ActionResult<Boolean> identifyDealOldData(String tenantId) {
return null;
}
@Override
public ActionResult<String> migrateOldTaskData(String tenantId) {
return null;
}
@Override
public ActionResult<String> migratePromotionOldData(String tenantId, String promotionId) {
return null;
}
};
}
}

View File

@@ -0,0 +1,205 @@
package jnpf.doclibrary;
import com.github.pagehelper.PageInfo;
import io.swagger.v3.oas.annotations.Operation;
import jnpf.base.ActionResult;
import jnpf.doclibrary.fallback.StoreFallback;
import jnpf.entity.StoreEntity;
import jnpf.model.store.Store;
import jnpf.model.store.StorePositionInfoVo;
import jnpf.model.store.StoreUserNumVo;
import jnpf.model.store.dto.StoreAbnormalIdsQueryDTO;
import jnpf.model.store.dto.StorePageByIdsNoDsQueryDTO;
import jnpf.model.store.dto.StorePageByIdsQueryDTO;
import jnpf.model.store.vo.StoreBaseListVO;
import jnpf.model.store.vo.StoreLocationVO;
import jnpf.model.store.vo.UserStoreListVo;
import jnpf.model.vo.StoreExecutionVo;
import jnpf.util.NoDataSourceBind;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 门店内部调用api
*
* @author yanwenfu
* @create 2023-07-12
*/
@FeignClient(name = "jnpf-ftb", fallback = StoreFallback.class, path = "/Store")
public interface StoreApi {
/**
* 查询门店下岗位的成员数量
* @param storeId 门店id
* @param positionList 岗位id集合
* @return java.util.List<jnpf.model.store.StorePositionInfoVo>
*/
@GetMapping(value = "/storePositionInfo/list")
List<StorePositionInfoVo> getStorePositionInfoList(@RequestParam(value = "storeId") String storeId, @RequestParam(value = "positionList") List<String> positionList);
/**
* 查询门店下的成员数量
* @param storeIds 门店ids
* @return java.util.List<jnpf.model.store.StorePositionInfoVo>
*/
@GetMapping(value = "/storePositionInfo/getUserNum")
List<StoreUserNumVo> getUserNum(@RequestParam(value = "storeIds") List<String> storeIds);
/**
* 获取用户门店列表信息
* @return 返回值
*/
@GetMapping(value = "/userStoreList")
ActionResult<List<Store>> getUserStoreList();
/**
* 获取用户门店列表信息(值班)
*
* @return 返回值
*/
@GetMapping(value = "/userStoreListDuty")
ActionResult<List<Store>> getUserStoreListDuty();
/**
* 查询用户所属的门店
* @param userId 用户id
* @return jnpf.base.ActionResult<java.util.List < jnpf.model.store.Store>>
*/
@GetMapping(value = "/listByUserId/{userId}")
List<Store> getListByUserId(@PathVariable(value = "userId") String userId);
@GetMapping(value = "/getAllUserStores")
List<UserStoreListVo> getAllUserStores();
/**
* 根据门店ids查询门店信息
* @param storeIds 门店ids
* @return java.util.List<jnpf.model.store.Store>
*/
@GetMapping(value = "/listByIds")
List<Store> getListByIds(@RequestParam(value = "storeIds") List<String> storeIds);
@GetMapping("/getList")
ActionResult<List<Store>> getList(@RequestParam("selectKey") String selectKey,
@RequestParam("organizeid") String organizeId,
@RequestParam("longitude") String longitude,
@RequestParam("latitude") String latitude);
/**
* 查询组织下的门店
* @param organizeId 组织id
* @return java.util.List<jnpf.model.store.Store>
*/
@GetMapping(value = "/list")
List<Store> getStoreList(@RequestParam(value = "organizeId", required = false) String organizeId);
/**
* 查询组织下的门店(返回了上级组织)
* @param organizeId 组织id
* @return java.util.List<jnpf.model.store.Store>
*/
@GetMapping(value = "/orgList")
List<Store> getOrgStoreList(@RequestParam(value = "organizeId", required = false) String organizeId, @RequestParam(value = "queryStoreIds", required = false) List<String> queryStoreIds);
/**
* 查询门店信息
* @param id 门店id
* @return jnpf.model.store.Store
*/
@GetMapping("/info/{id}")
Store getStoreInfo(@PathVariable("id") String id);
/**
* 查询门店信息
* @param id 门店id
* @return jnpf.model.store.Store
*/
@GetMapping("/getStoreInfoNoData")
StoreEntity getStoreInfoNoData(@RequestParam("id") String id, @RequestParam("tenantId") String tenantId);
/**
* 根据门店ids分页查询门店记录
* @param storeIds 门店ids
* @param currentPage 当前页码
* @param pageSize 每页条数
* @return com.github.pagehelper.PageInfo<jnpf.model.vo.StoreExecutionVo>
*/
@PostMapping(value = "/store/pageByIds")
PageInfo<StoreExecutionVo> getStorePageByIds(@RequestBody StorePageByIdsQueryDTO query);
/**
* 根据门店ids分页查询门店记录
* @param storeIds 门店ids
* @param currentPage 当前页码
* @param pageSize 每页条数
* @return com.github.pagehelper.PageInfo<jnpf.model.vo.StoreExecutionVo>
*/
@PostMapping(value = "/store/pageByIdsNoDataSource")
PageInfo<StoreExecutionVo> getStorePageByIdsNoDataSource(@RequestBody StorePageByIdsNoDsQueryDTO query);
/**
* 查询异常的门店
* @param storeIds 门店ids
* @return java.util.List<java.lang.String>
*/
@PostMapping(value = "/store/abnormal/record")
List<String> getAbnormalStoreIds(@RequestBody StoreAbnormalIdsQueryDTO query);
/**
* 根据组织ids查询门店列表
* @param organizeIdList 组织ids
* @return java.util.List<jnpf.model.store.Store>
*/
@PostMapping(value = "/store/list/byOrganizeList")
List<Store> getStoreListByOrganizeList(@RequestBody List<String> organizeIdList);
/**
* 查询门店信息(未绑定数据库)
* @param tenantId 租户id
* @param storeIds 门店ids
* @return java.util.List<jnpf.model.store.Store>
*/
@GetMapping(value = "/store/list/noDataSource")
List<Store> getListByIdsNoDataSource(@RequestParam(value = "tenantId") String tenantId, @RequestParam(value = "storeIds") List<String> storeIds);
/**
* 校验是否是值班人
* @param userId 用户Id
*/
@GetMapping(value = "/store/checkStoreUser")
boolean checkStoreUser(@RequestParam(value = "userId") String userId);
@Operation(description = "[列表] 目标组织,及其子组织所有已启用的门店")
@GetMapping(value = "/store/list/organizeChildren")
ActionResult<List<StoreBaseListVO>> getStoreListByOrganizeIdAndChildOrganize(@RequestParam(value = "organizeId") String organizeId, @RequestParam(required = false, value = "disabled") Boolean disabled);
/**
* 查询门店下岗位的成员数量
* @param storeId 门店id
* @param positionList 岗位id集合
* @return java.util.List<jnpf.model.store.StorePositionInfoVo>
*/
@NoDataSourceBind
@GetMapping(value = "/storePositionInfo/list/nodata")
List<StorePositionInfoVo> getStorePositionInfoListNodata(@RequestParam(value = "storeId") String storeId, @RequestParam(value = "positionList") List<String> positionList, @RequestParam(value = "tenantId") String tenantId);
/**
* 查询用户所属的门店
* @param userId 用户id
* @return jnpf.base.ActionResult<java.util.List < jnpf.model.store.Store>>
*/
@GetMapping(value = "/listByUserId/nodata/{userId}")
@NoDataSourceBind
List<Store> getListByUserIdNodata(@PathVariable(value = "userId") String userId, @RequestParam(value = "tenantId") String tenantId);
/**
* 获取门店位置信息
* @param storeId 门店id
* @return jnpf.model.store.vo.StoreLocationVO
*/
@GetMapping(value = "/getStoreLocation")
StoreLocationVO getStoreLocation(@RequestParam(value = "storeId") String storeId);
}

View File

@@ -0,0 +1,178 @@
package jnpf.doclibrary.fallback;
import com.github.pagehelper.PageInfo;
import jnpf.base.ActionResult;
import jnpf.doclibrary.StoreApi;
import jnpf.entity.StoreEntity;
import jnpf.model.store.Store;
import jnpf.model.store.StorePositionInfoVo;
import jnpf.model.store.StoreUserNumVo;
import jnpf.model.store.dto.StoreAbnormalIdsQueryDTO;
import jnpf.model.store.dto.StorePageByIdsNoDsQueryDTO;
import jnpf.model.store.dto.StorePageByIdsQueryDTO;
import jnpf.model.store.vo.StoreBaseListVO;
import jnpf.model.store.vo.StoreLocationVO;
import jnpf.model.store.vo.UserStoreListVo;
import jnpf.model.vo.StoreExecutionVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
/**
* 资料库内部调用fallback
*
* @author yanwenfu
* @create 2023-07-12
*/
@Slf4j
@Component
public class StoreFallback implements StoreApi {
@Override
public List<StorePositionInfoVo> getStorePositionInfoList(String storeId, List<String> positionList) {
log.error("类名: StoreFallback, 方法名: getStorePositionInfoList, 错误信息: 调用失败...");
return new ArrayList<>();
}
@Override
public List<StoreUserNumVo> getUserNum(List<String> storeIds) {
log.error("类名: StoreFallback, 方法名: getUserNum, 错误信息: 调用失败...");
return new ArrayList<>();
}
@Override
public List<Store> getListByUserId(String userId) {
log.error("类名: StoreFallback, 方法名: getStoreListByUser, 错误信息: 调用失败...");
return new ArrayList<>();
}
@Override
public List<UserStoreListVo> getAllUserStores() {
log.error("类名: StoreFallback, 方法名: getAllUserStores, 错误信息: 调用失败...");
return null;
}
@Override
public List<Store> getListByIds(List<String> storeIds) {
log.error("类名: StoreFallback, 方法名: getListByIds, 错误信息: 调用失败...");
return new ArrayList<>();
}
@Override
public ActionResult<List<Store>> getList(String selectKey, String organizeId, String longitude, String latitude) {
log.error("类名: StoreFallback, 方法名: getList, 错误信息: 调用失败...");
return null;
}
@Override
public ActionResult<List<Store>> getUserStoreList() {
log.error("类名: StoreFallback, 方法名: getUserStoreList, 错误信息: 调用失败...");
return null;
}
@Override
public ActionResult<List<Store>> getUserStoreListDuty() {
return null;
}
@Override
public List<Store> getStoreList(String organizeId) {
log.error("类名: StoreFallback, 方法名: getStoreList, 错误信息: 调用失败...");
return new ArrayList<>();
}
@Override
public List<Store> getOrgStoreList(String organizeId, List<String> queryStoreIds) {
log.error("类名: StoreFallback, 方法名: getOrgStoreList, 错误信息: 调用失败...");
return null;
}
@Override
public Store getStoreInfo(String id) {
log.error("类名: StoreFallback, 方法名: getStoreInfo, 错误信息: 调用失败...");
return null;
}
/**
* 查询门店信息
*
* @param id 门店id
* @param tenantId
* @return jnpf.model.store.Store
*/
@Override
public StoreEntity getStoreInfoNoData(String id, String tenantId) {
log.error("FTB_类名: StoreFallback, 方法名: getStoreInfoDutyQuery, 错误信息: 调用失败..., 当前租户号[{}] - 门店号[{}]", tenantId, id);
log.error(" getStoreInfoDutyQuery 没有拿到门店信息,走了fallback");
return null;
}
@Override
public PageInfo<StoreExecutionVo> getStorePageByIds(StorePageByIdsQueryDTO query) {
return new PageInfo<>();
}
@Override
public boolean checkStoreUser(String userId) {
log.error("类名: StoreFallback, 方法名: checkStoreUser, 错误信息: 调用失败...");
return false;
}
@Override
public ActionResult<List<StoreBaseListVO>> getStoreListByOrganizeIdAndChildOrganize(String organizeId, Boolean disabled) {
return null;
}
@Override
public List<StorePositionInfoVo> getStorePositionInfoListNodata(String storeId, List<String> positionList, String tenantId) {
return null;
}
@Override
public List<Store> getListByUserIdNodata(String userId, String tenantId) {
return null;
}
@Override
public StoreLocationVO getStoreLocation(String storeId) {
return null;
}
@Override
public PageInfo<StoreExecutionVo> getStorePageByIdsNoDataSource(StorePageByIdsNoDsQueryDTO query) {
return new PageInfo<>();
}
@Override
public List<String> getAbnormalStoreIds(StoreAbnormalIdsQueryDTO query) {
return new ArrayList<>();
}
@Override
public List<Store> getStoreListByOrganizeList(List<String> organizeIdList) {
return new ArrayList<>();
}
@Override
public List<Store> getListByIdsNoDataSource(String tenantId, List<String> storeIds) {
return new ArrayList<>();
}
// @Override
// public ActionResult<Store> info(String id) {
// return null;
// }
}

View File

@@ -0,0 +1,43 @@
package jnpf.exam;
import jnpf.base.ActionResult;
import jnpf.exam.fallback.V2CultivateTimingApiFallback;
import jnpf.util.NoDataSourceBind;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(name = "jnpf-ftb", fallback = V2CultivateTimingApiFallback.class, path = "/v2/cultivate/timing")
public interface V2CultivateTimingApi {
/**
* 培训相关每分钟执行
*
* @return 响应
*/
@NoDataSourceBind
@GetMapping("/per-minute")
ActionResult<Integer> perMinute(@RequestParam("tenantId") String tenantId);
/**
* 每小时执行
*
* @param tenantId 租户ID
* @return 响应
*/
@NoDataSourceBind
@GetMapping("/per-hour")
ActionResult<Integer> perHour(@RequestParam("tenantId") String tenantId);
/**
* 每半个小时执行
*
* @param tenantId 租户ID
* @return 响应
*/
@NoDataSourceBind
@GetMapping("/per-half-hour")
ActionResult<Integer> perHalfHour(@RequestParam("tenantId") String tenantId);
}

View File

@@ -0,0 +1,25 @@
package jnpf.exam.fallback;
import jnpf.base.ActionResult;
import jnpf.exam.V2CultivateTimingApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class V2CultivateTimingApiFallback implements V2CultivateTimingApi {
@Override
public ActionResult<Integer> perMinute(String tenantId) {
return null;
}
@Override
public ActionResult<Integer> perHour(String tenantId) {
return null;
}
@Override
public ActionResult<Integer> perHalfHour(String tenantId) {
return null;
}
}

View File

@@ -0,0 +1,71 @@
package jnpf.franchisee;
import jnpf.franchisee.fallback.FranchiseeFallbackApi;
import jnpf.model.franchisee.vo.FranchiseeIdName;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import java.util.Collection;
import java.util.List;
@FeignClient(name = "jnpf-ftb", fallback = FranchiseeFallbackApi.class, path = "/web/franchise-api")
public interface FranchiseeApi {
/**
* 获取所有加盟商信息
* @return
*/
@GetMapping("/getFranchiseeIdNameList")
List<FranchiseeIdName> getFranchiseeIdNameList();
/**
* 根据ID列表获取加盟商信息
* @param ids
* @return
*/
@GetMapping("/getFranchiseeIdNameListByIds")
List<FranchiseeIdName> getFranchiseeIdNameListByIds(Collection<String> ids);
/**
* 根据ID获取加盟商信息
* @param id
* @return
*/
@GetMapping("/getFranchiseeIdNameListById")
FranchiseeIdName getFranchiseeIdNameListById(String id);
/**
* 根据名称获取加盟商信息
* @param name
* @return
*/
@GetMapping("/getFranchiseeIdNameListByName")
List<FranchiseeIdName> getFranchiseeIdNameListByName(String name);
/**
* 根据名称列表获取加盟商信息
* @param names
* @return
*/
@GetMapping("/getFranchiseeIdNameListByNames")
List<FranchiseeIdName> getFranchiseeIdNameListByNames(Collection<String> names);
/**
* 根据编码获取加盟商信息
* @param code
* @return
*/
@GetMapping("/getFranchiseeIdNameListByCode")
FranchiseeIdName getFranchiseeIdNameListByCode(String code);
/**
* 根据编码列表获取加盟商信息
* @param codes
* @return
*/
@GetMapping("/getFranchiseeIdNameListByCodes")
List<FranchiseeIdName> getFranchiseeIdNameListByCodes(Collection<String> codes);
}

View File

@@ -0,0 +1,55 @@
package jnpf.franchisee.fallback;
import jnpf.franchisee.FranchiseeApi;
import jnpf.model.franchisee.vo.FranchiseeIdName;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.Collection;
import java.util.List;
@Slf4j
@Component
public class FranchiseeFallbackApi implements FranchiseeApi {
@Override
public List<FranchiseeIdName> getFranchiseeIdNameList() {
log.error("getFranchiseeIdNameList fallback");
return null;
}
@Override
public List<FranchiseeIdName> getFranchiseeIdNameListByIds(Collection<String> ids) {
log.error("getFranchiseeIdNameListByIds fallback.ids:{}",ids);
return null;
}
@Override
public FranchiseeIdName getFranchiseeIdNameListById(String id) {
log.error("getFranchiseeIdNameListById fallback.id{}",id);
return null;
}
@Override
public List<FranchiseeIdName> getFranchiseeIdNameListByName(String name) {
log.error("getFranchiseeIdNameListByName fallback.name{}",name);
return null;
}
@Override
public List<FranchiseeIdName> getFranchiseeIdNameListByNames(Collection<String> names) {
log.error("getFranchiseeIdNameListByNames fallback.names{}",names);
return null;
}
@Override
public FranchiseeIdName getFranchiseeIdNameListByCode(String code) {
log.error("getFranchiseeIdNameListByCode fallback.names{}",code);
return null;
}
@Override
public List<FranchiseeIdName> getFranchiseeIdNameListByCodes(Collection<String> codes) {
log.error("getFranchiseeIdNameListByCodes fallback.names{}",codes);
return null;
}
}

View File

@@ -0,0 +1,23 @@
package jnpf.notice;
import jnpf.base.ActionResult;
import jnpf.notice.fallback.FtbNoticeFallBackApi;
import jnpf.util.NoDataSourceBind;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(name = "jnpf-ftb", fallback = FtbNoticeFallBackApi.class, path = "/web/noticeAnnouncements")
public interface FtbNoticeApi {
/**
* 每半个小时检测一下是否有发布的通知公告
*
* @param tenantId 租户ID
* @return
*/
@NoDataSourceBind
@GetMapping("/checkPublishNotice")
ActionResult<Boolean> checkPublishNotice(@RequestParam("tenantId") String tenantId);
}

View File

@@ -0,0 +1,18 @@
package jnpf.notice.fallback;
import jnpf.base.ActionResult;
import jnpf.notice.FtbNoticeApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class FtbNoticeFallBackApi implements FtbNoticeApi {
@Override
public ActionResult<Boolean> checkPublishNotice(String tenantId) {
return null;
}
}

View File

@@ -0,0 +1,72 @@
package jnpf.personnels;
import jnpf.model.attendance.vo.DailyApprovalVo;
import jnpf.model.personnels.dto.emp.FtbEmpQueryDTO;
import jnpf.model.personnels.dto.roster.meta.FtbPersonnlesJobTenureDTO;
import jnpf.model.personnels.dto.secondment.FtbSecondMentQueryDTO;
import jnpf.model.personnels.dto.staff.roster.FtbPersonnelsStaffRosterDto;
import jnpf.model.personnels.vo.roster.FtbPersonnelsChangeInfoVO;
import jnpf.model.personnels.vo.roster.FtbPersonnlesJobTenureVO;
import jnpf.model.personnels.vo.secondment.FtbPersonnelsSecondmentVO;
import jnpf.util.NoDataSourceBind;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
import java.util.Map;
/**
* @Author: peng.hao
* @create: 2025/10/3
*/
@FeignClient(name = "jnpf-ftb")
public interface FtbPersonneApi {
/**
*根据userId 查询人事异动信息
*/
@GetMapping("/web-app/staff-home-page/get-personnel-change-info")
FtbPersonnelsChangeInfoVO getPersonnelChangeInfo(@RequestParam(name = "userId") String userId);
@PostMapping("/web-app/staff-home-page/get-personnel-change-info-batch")
Map<String, FtbPersonnelsChangeInfoVO> getPersonnelChangeInfoBatch(@RequestBody List<String> userIds);
/**
* 根据userI 和开始时间结束时间查询借调记录
*/
@GetMapping("/web/secondment/get-secondment-record")
List<FtbPersonnelsSecondmentVO> getSecondmentRecord(@RequestParam("userId") String userId,
@RequestParam(value = "startLeaveTime",required = false) String startLeaveTime,
@RequestParam(value = "endLeaveTime",required = false)String endLeaveTime);
/**
* 批量查询审批中和审批完成的借调记录
*/
@PostMapping("/web/secondment/get-secondment-record-bath")
List<FtbPersonnelsSecondmentVO> getSecondmentRecordBath(@RequestBody FtbSecondMentQueryDTO dto);
/**
* 查询审批中和审批完成的借调记录
*/
@PostMapping("/web/secondment/list-query-approval")
List<DailyApprovalVo> queryListApproval(@RequestBody FtbSecondMentQueryDTO dto);
/**
* 模糊搜索 电话 名称
*/
@PostMapping("/web/personnels-emp-entry/search-phone-name")
List<FtbPersonnelsStaffRosterDto> searchPhoneName(@RequestBody FtbEmpQueryDTO dto);
/**
* 查询岗龄
* @param req
* @return
*/
@PostMapping("/web-app/staff-home-page/query-positionTenure-age")
@NoDataSourceBind
List<FtbPersonnlesJobTenureVO> queryPositionTenureAge(@RequestBody FtbPersonnlesJobTenureDTO req);
}

View File

@@ -0,0 +1,38 @@
package jnpf.personnels;
import jnpf.base.ActionResult;
import jnpf.model.personnels.dto.contractinfo.ContactStatusInfo;
import jnpf.personnels.fallback.FtbPersonnelsContaceInfoManagerFallBackApi;
import jnpf.util.NoDataSourceBind;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(name = "jnpf-ftb", fallback = FtbPersonnelsContaceInfoManagerFallBackApi.class, path = "/web/personnelsContactInfo")
public interface FtbPersonnelsContactInfoManagerApi {
/**
* 同步合同信息
*
* @param info
* @return
*/
@PostMapping("/syncContactInfo")
@NoDataSourceBind
ActionResult<Boolean> syncContactInfo(@RequestBody ContactStatusInfo info);
/**
* 定时任务检测未签署合同消息
*
* @param tenantId
* @return
*/
@GetMapping("/checkNotSendContactSign")
@NoDataSourceBind
ActionResult<Boolean> checkNotSendContactSign(@RequestParam("tenantId") String tenantId);
}

View File

@@ -0,0 +1,19 @@
package jnpf.personnels;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
* 入职api
*/
@FeignClient(name = "jnpf-ftb", path = "/web/personnels-emp-entry")
public interface FtbPersonnelsEmEntryApi {
/**
* 根据userId修改手机号信息
*/
@PutMapping("/update-phone-by-userId")
void updatePhoneByUserId( @RequestParam("userId") String userId,
@RequestParam("phone") String phone);
}

View File

@@ -0,0 +1,30 @@
package jnpf.personnels;
import jnpf.model.personnels.vo.employeetype.FtbPersonnelsEmployeeTypeVO;
import jnpf.personnels.fallback.FtbPersonnelsEmployeeTypeRemoteFallBackApi;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.List;
import java.util.Map;
/**
* 员工类型模块
*
* @author wangchunxiang
* @date 2025/09/30
*/
@FeignClient(name = "jnpf-ftb", fallback = FtbPersonnelsEmployeeTypeRemoteFallBackApi.class, path = "/web/employee-type")
public interface FtbPersonnelsEmployeeTypeRemoteApi {
/**
* 根据用户ID集合查询员工类型ID、名称
*
* @param userIds 用户ID集合
* @return key为用户Idvalue为员工类型
*/
@PostMapping("/get-employee-type-by-user-ids")
Map<String, FtbPersonnelsEmployeeTypeVO> getEmployeeTypeByUserIds(@RequestBody List<String> userIds);
}

View File

@@ -0,0 +1,28 @@
package jnpf.personnels;
import jnpf.base.ActionResult;
import jnpf.model.personnels.dto.oa.FtbPersonnelsEmployInfoForOA;
import jnpf.personnels.fallback.FtbPersonnelsEmploymentApplyFallBackApi;
import jnpf.util.NoDataSourceBind;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@FeignClient(name = "jnpf-ftb", fallback = FtbPersonnelsEmploymentApplyFallBackApi.class, path = "/web/personnels-staff-employment-apply")
public interface FtbPersonnelsEmploymentApplyApi {
@GetMapping("/updateEmploymentApplyStatus")
@NoDataSourceBind
public ActionResult updateEmploymentApplyStatus(@RequestParam("tenantId") String tenantId);
/**
* 入职办理列表查询 ForOA 回显 姓名 手机
*/
@GetMapping("/inquire-about-the-entry-list")
ActionResult<List<FtbPersonnelsEmployInfoForOA>> inquireAboutTheEntryList(@RequestParam(required = false, name = "keyWords") String keyWords,
@RequestParam(required = false,name = "phone")String phone,
@RequestParam(required = false,name = "workerName")String workerName);
}

View File

@@ -0,0 +1,44 @@
package jnpf.personnels;
import jnpf.base.ActionResult;
import jnpf.model.personnels.dto.oa.FtbPersonnelsEmployInfoForOA;
import jnpf.model.personnels.vo.range.FtbRangeConfigDIYVO;
import jnpf.model.personnels.vo.range.FtbRangeConfigVO;
import jnpf.personnels.fallback.FtbPersonnelsEmploymentApplyFallBackApi;
import jnpf.personnels.fallback.FtbPersonnelsInfoConfigBackApi;
import jnpf.util.NoDataSourceBind;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import javax.annotation.Resource;
import java.util.List;
@FeignClient(name = "jnpf-ftb", fallback = FtbPersonnelsInfoConfigBackApi.class, path = "/web/range-config")
public interface FtbPersonnelsInfoConfigApi {
/**
* 查询是平均范围配置 还是自定义配置
* @param type 1 年龄 2 薪资 3 工龄
* @return 配置类型 1平均 2自定义
*/
@GetMapping("/query-type")
ActionResult<Integer> queryType(@RequestParam("type") Integer type);
/**
* 查询平均区间配置范围
* @param type 1 年龄 2 薪资 3 工龄
*/
@GetMapping("/query-info")
ActionResult<FtbRangeConfigVO> queryInfo(@RequestParam("type") Integer type);
/**
* 查询自定义区间配置范围
*
* @param type 1 年龄 2 薪资 3 工龄
*/
@GetMapping("/query-info-diy")
ActionResult<List<FtbRangeConfigDIYVO>> queryDiyInfo(@RequestParam("type") Integer type);
}

View File

@@ -0,0 +1,59 @@
package jnpf.personnels;
import jnpf.model.personnels.dto.roster.meta.PersonnelsMetaDTO;
import jnpf.model.personnels.dto.salary.FtbXcCustomFieldDto;
import jnpf.model.personnels.req.roster.FtbPersonnelsMetaDataReq;
import jnpf.model.personnels.req.roster.FtbPersonnelsMetaFuctionReq;
import jnpf.model.personnels.vo.salary.FtbXcCustomFieldVo;
import jnpf.personnels.fallback.FtbPersonnelsMetaDataManagerFallBackApi;
import jnpf.util.NoDataSourceBind;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
import java.util.Date;
import java.util.List;
import java.util.Map;
@FeignClient(name = "jnpf-ftb", fallback = FtbPersonnelsMetaDataManagerFallBackApi.class, path = "/web/personnels/metaData")
public interface FtbPersonnelsMetaDataManagerApi {
@PostMapping("/getMetaData")
@NoDataSourceBind
public List<PersonnelsMetaDTO> getMetaData(@RequestBody FtbPersonnelsMetaDataReq info);
/**
* 查询用户当月是否已经离职
*
* @param userId 用户ID
* @param tenantId 租户ID
* @return true-已经离职 false-未离职
*/
@GetMapping("/queryCurrMonthDepartStatus/{userId}/{tenantId}")
@NoDataSourceBind
public Boolean queryCurrMonthDepartStatus(@PathVariable("userId") String userId, @PathVariable("tenantId") String tenantId);
/**
* 查询用户当月是否已经离职
*
* @param req 请求
* @return true-已经离职 false-未离职
*/
@PostMapping("/queryCurrMonthDepartStatusByDate")
@NoDataSourceBind
Boolean queryCurrMonthDepartStatusByDate(@RequestBody FtbPersonnelsMetaFuctionReq req);
/**
* 批量查询员工是否离职
*/
@PostMapping("/query-current-month-leave")
@NoDataSourceBind
Map<String,Boolean> queryCurrMonthLeave(@RequestBody FtbPersonnelsMetaFuctionReq req);
/**
* 批量查询员工自定义字段
*/
@PostMapping("/query-custom-filed")
List<FtbXcCustomFieldVo> queryCustomFiled(@RequestBody FtbXcCustomFieldDto req);
}

View File

@@ -0,0 +1,50 @@
package jnpf.personnels;
import jnpf.model.personnels.dto.rewardspunishments.FtbPersonnelSalaryRewardDTO;
import jnpf.model.personnels.dto.salary.FtbSalaryMetaDataQueryDto;
import jnpf.model.personnels.vo.rewardspunishments.FtbPersonnelSalaryRewardVO;
import jnpf.model.personnels.vo.rewardspunishments.FtbXcEmployeeRewardRecordsVO;
import jnpf.util.NoDataSourceBind;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
* 查询指定用户,指定月份内,被奖励和处罚的合计
*/
@FeignClient(name = "jnpf-ftb", path = "/ftb-personnels-rewards-punishments")
public interface FtbPersonnelsRewardsPunishmentsApi {
/**
* 薪酬奖励合计
*/
@PostMapping(value = "/salary-reward")
List<FtbPersonnelSalaryRewardVO> salaryReward(@RequestBody FtbPersonnelSalaryRewardDTO ftbPersonnelSalaryRewardDTO);
/**
* 薪酬惩罚合计
*/
@PostMapping(value = "/pay-penalty")
List<FtbPersonnelSalaryRewardVO> totalSalaryPenalty(@RequestBody FtbPersonnelSalaryRewardDTO ftbPersonnelSalaryRewardDTO);
/**
* 薪酬获取奖励和惩罚api
*/
@PostMapping(value = "/salaryMetaDataQuery")
@NoDataSourceBind
BigDecimal salaryMetaDataQuery(@RequestBody FtbSalaryMetaDataQueryDto dto);
/**
* 薪酬获取奖励和惩罚api(批量)
*/
@PostMapping(value = "/salary-meta-data-batch-query")
@NoDataSourceBind
List<FtbXcEmployeeRewardRecordsVO> salaryBatchMetaDataQuery(@RequestBody FtbSalaryMetaDataQueryDto dto);
}

View File

@@ -0,0 +1,25 @@
package jnpf.personnels;
import jnpf.base.ActionResult;
import jnpf.model.personnels.vo.rewardspunishments.FtbPersonnelsRewardsPunishmentApprovalVO;
import jnpf.personnels.fallback.FtbPersonnelsRewardsPunishmentsRemoteFallBackApi;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@FeignClient(name = "jnpf-ftb", path = "/ftb-personnels-rewards-punishments", fallback = FtbPersonnelsRewardsPunishmentsRemoteFallBackApi.class)
public interface FtbPersonnelsRewardsPunishmentsRemoteApi {
/**
* OA审批获取奖惩规则
*
* @param type 类型0奖励1惩罚
* @return {@link ActionResult }
*/
@GetMapping(value = "/list-approval")
ActionResult<List<FtbPersonnelsRewardsPunishmentApprovalVO>> listApproval(@RequestParam("type") Integer type);
}

View File

@@ -0,0 +1,147 @@
package jnpf.personnels;
import io.swagger.v3.oas.annotations.Operation;
import jnpf.base.ActionResult;
import jnpf.base.vo.PageListVO;
import jnpf.model.personnels.dto.roster.QueryCompanyAgeDto;
import jnpf.model.personnels.dto.staff.employment.FtbPersonnelsStaffEmploymentApplyDto;
import jnpf.model.personnels.dto.staff.roster.FtbPersonnelsStaffRosterDto;
import jnpf.model.personnels.dto.staff.roster.ShopManagerUserDto;
import jnpf.model.personnels.dto.staff.roster.StaffRosterInfoDto;
import jnpf.model.personnels.req.roster.StaffRosterListReq;
import jnpf.model.personnels.req.roster.StaffRosterReq;
import jnpf.permission.model.user.UserListVO;
import jnpf.permission.vo.user.UserListMatchVO;
import jnpf.personnels.fallback.FtbPersonnelsRosterManagerFallBackApi;
import jnpf.util.NoDataSourceBind;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.cloud.openfeign.SpringQueryMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@FeignClient(name = "jnpf-ftb", fallback = FtbPersonnelsRosterManagerFallBackApi.class, path = "/web/personnels-staff-roster")
public interface FtbPersonnelsRosterManagerApi {
@NoDataSourceBind
@GetMapping("/updateCompanyAge")
ActionResult updateCompanyAge(@RequestParam("tenantId") String tenantId);
/**
* 绑定手机号
*
* @param userId 用户ID
* @param phone 手机号
* @return
*/
@PostMapping("/bindPhone")
@NoDataSourceBind
public ActionResult<Boolean> bindPhone(@RequestParam("tenantCode") String tenantCode, @RequestParam("userId") String userId, @RequestParam("phone") String phone);
@NoDataSourceBind
@PostMapping("/queryCompanyAge/{tenantId}")
ActionResult<List<QueryCompanyAgeDto>> queryCompanyAge(@RequestBody List<String> userIds, @PathVariable("tenantId") String tenantId);
/**
* 查询未提交入职登记表的用户
*
* @param tenantId
* @return
*/
@NoDataSourceBind
@GetMapping("/queryNoSubmitForm")
ActionResult<List<StaffRosterInfoDto>> queryNoSubmitForm(@RequestParam("tenantId") String tenantId);
/**
* 查询健康证过期的用户
*
* @param tenantId
* @param days 距离健康证 快过期的天数
* @return
*/
@NoDataSourceBind
@GetMapping("/queryHealthExpire")
ActionResult<List<StaffRosterInfoDto>> queryHealthExpire(@RequestParam("tenantId") String tenantId, @RequestParam(value = "days", required = false) Long days, @RequestParam(value = "months", required = false) Long months);
/**
* 花名册查询列表
*
* @param req
* @return {@link ActionResult}<{@link FtbPersonnelsStaffEmploymentApplyDto}>
*/
@GetMapping("/query-list")
ActionResult<PageListVO<FtbPersonnelsStaffRosterDto>> pageLists(@Validated @SpringQueryMap StaffRosterListReq req);
/**
* 花名册查询列表 _post
*
* @param req
* @return {@link ActionResult}<{@link FtbPersonnelsStaffEmploymentApplyDto}>
*/
@PostMapping("/query-list/postWithSalary")
ActionResult<PageListVO<FtbPersonnelsStaffRosterDto>> postWithSalary(@Validated @RequestBody StaffRosterListReq req);
/**
* 花名册查询列表不分页
*/
@PostMapping("/query-list/post-with-salary-no-page")
List<FtbPersonnelsStaffRosterDto> postWithSalaryNoPage(@Validated @RequestBody StaffRosterListReq req);
/**
* 花名册列表查询-无权限
* @param req
* @return ActionResult<FtbPersonnelsStaffRosterDto>
*/
@PostMapping("/query-list/byUserIds")
ActionResult<List<FtbPersonnelsStaffRosterDto>> getPersonnelByUserIds(@RequestBody StaffRosterListReq req);
@PostMapping("/query-list/post")
ActionResult<PageListVO<FtbPersonnelsStaffRosterDto>> pageListsPost(@Validated @RequestBody StaffRosterListReq req);
/**
* 查询离职人员信息
* @return
*/
@PostMapping("/queryDepartUser")
ActionResult<List<FtbPersonnelsStaffRosterDto>> queryDepartUser(@RequestBody List<String> userIds);
@Operation(summary = "[匹配]-指定user们哪些存在,哪些不存在, 包含花名册离职的用户")
@PostMapping("/user/list/match/ids")
ActionResult<UserListMatchVO> getUserListByMatch(@RequestBody List<String> userIds);
/**
* 根据用户ID查询所属门店负责人信息
*
* @param tenantId
* @param userIds 用户ID
* @return
*/
@NoDataSourceBind
@PostMapping("/queryShopManagerUser/{tenantId}")
ActionResult<ShopManagerUserDto> queryShopManagerUser(@PathVariable("tenantId") String tenantId, @RequestBody List<String> userIds);
@NoDataSourceBind
@GetMapping("/timingAlertTrialJob/{tenantId}")
@Deprecated(since = "人事2.1废弃试岗状态")
ActionResult<List<UserListVO>> timingAlertTrialJob(@PathVariable("tenantId") String tenantId);
/**
* 根据用户ID查询用户信息
* @param req
* @return
*/
@PostMapping("/queryWithUserIds")
List<FtbPersonnelsStaffRosterDto> queryWithUserIds( @RequestBody StaffRosterListReq req);
/**
* 查询指定userIds用户信息
*/
@PostMapping("/queryWithUserIds/post")
List<FtbPersonnelsStaffRosterDto> queryWithUserIdsPost(@RequestBody StaffRosterReq req);
}

View File

@@ -0,0 +1,52 @@
package jnpf.personnels;
import jnpf.base.ActionResult;
import jnpf.model.personnels.dto.turnover.FtbDepUserDTO;
import jnpf.model.personnels.vo.turnover.FtbPersonnelsTurnoverManagementVO;
import jnpf.permission.vo.v2.user.UserBoundVO;
import jnpf.personnels.fallback.FtbPersonnelsTurnoverManagementFallBackApi;
import jnpf.util.NoDataSourceBind;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
/**
* @Title: FtbPersonnelsTurnoverManagementApi
* @Author: peng.hao
* @create: 2024/2/19 10:36
*/
@FeignClient(name = "jnpf-ftb", fallback = FtbPersonnelsTurnoverManagementFallBackApi.class, path = "/web/personnels-turnover")
public interface FtbPersonnelsTurnoverManagementApi {
@GetMapping("/closeUserAccountRegularlyAfterResignation")
@NoDataSourceBind
ActionResult<String> closeUserAccountRegularlyAfterResignation(@RequestParam("tenantId") String tenantId);
/**
* 离职用户已签署离职协议
* @param userId 用户id
* @return
*/
@GetMapping("/user-has-sign-an-agreement")
Boolean userHasSignedASeparationAgreement(@RequestParam("userId") String userId,@RequestParam("flag") Integer flag);
/**
* 获取所有离职人员信息
*/
@GetMapping("/query-turnover-list")
List<FtbPersonnelsTurnoverManagementVO> queryTurnoverList();
/**
* 获取离职人员信息
* 1.按多个userId
* 2.按多个组织id
* 3.按多个岗位id
*/
@PostMapping("/get-dep-user")
List<UserBoundVO> getInformationAboutTheDepartingPerson(@RequestBody FtbDepUserDTO dto);
@PostMapping("/not-token-get-dep-user")
List<UserBoundVO> getInformationAboutTheDepartingPersonNotToken(@RequestBody FtbDepUserDTO dto);
}

View File

@@ -0,0 +1,24 @@
package jnpf.personnels.fallback;
import jnpf.base.ActionResult;
import jnpf.model.personnels.dto.contractinfo.ContactStatusInfo;
import jnpf.personnels.FtbPersonnelsContactInfoManagerApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class FtbPersonnelsContaceInfoManagerFallBackApi implements FtbPersonnelsContactInfoManagerApi {
@Override
public ActionResult<Boolean> syncContactInfo(ContactStatusInfo info) {
return null;
}
@Override
public ActionResult<Boolean> checkNotSendContactSign(String tenantId) {
return null;
}
}

View File

@@ -0,0 +1,18 @@
package jnpf.personnels.fallback;
import jnpf.model.personnels.vo.employeetype.FtbPersonnelsEmployeeTypeVO;
import jnpf.personnels.FtbPersonnelsEmployeeTypeRemoteApi;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
@Component
public class FtbPersonnelsEmployeeTypeRemoteFallBackApi implements FtbPersonnelsEmployeeTypeRemoteApi {
@Override
public Map<String, FtbPersonnelsEmployeeTypeVO> getEmployeeTypeByUserIds(List<String> userIds) {
return null;
}
}

View File

@@ -0,0 +1,26 @@
package jnpf.personnels.fallback;
import jnpf.base.ActionResult;
import jnpf.model.personnels.dto.oa.FtbPersonnelsEmployInfoForOA;
import jnpf.personnels.FtbPersonnelsEmploymentApplyApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
@Slf4j
public class FtbPersonnelsEmploymentApplyFallBackApi implements FtbPersonnelsEmploymentApplyApi {
@Override
public ActionResult updateEmploymentApplyStatus(String tenantId) {
return null;
}
@Override
public ActionResult<List<FtbPersonnelsEmployInfoForOA>> inquireAboutTheEntryList(String keyWords, String phone, String workerName) {
return null;
}
}

View File

@@ -0,0 +1,29 @@
package jnpf.personnels.fallback;
import jnpf.base.ActionResult;
import jnpf.model.personnels.vo.range.FtbRangeConfigDIYVO;
import jnpf.model.personnels.vo.range.FtbRangeConfigVO;
import jnpf.personnels.FtbPersonnelsInfoConfigApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
@Slf4j
public class FtbPersonnelsInfoConfigBackApi implements FtbPersonnelsInfoConfigApi {
@Override
public ActionResult<Integer> queryType(Integer type) {
return null;
}
@Override
public ActionResult<FtbRangeConfigVO> queryInfo(Integer type) {
return null;
}
@Override
public ActionResult<List<FtbRangeConfigDIYVO>> queryDiyInfo(Integer type) {
return null;
}
}

View File

@@ -0,0 +1,47 @@
package jnpf.personnels.fallback;
import jnpf.model.personnels.dto.roster.meta.PersonnelsMetaDTO;
import jnpf.model.personnels.dto.salary.FtbXcCustomFieldDto;
import jnpf.model.personnels.req.roster.FtbPersonnelsMetaDataReq;
import jnpf.model.personnels.req.roster.FtbPersonnelsMetaFuctionReq;
import jnpf.model.personnels.vo.salary.FtbXcCustomFieldVo;
import jnpf.personnels.FtbPersonnelsMetaDataManagerApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Component
@Slf4j
public class FtbPersonnelsMetaDataManagerFallBackApi implements FtbPersonnelsMetaDataManagerApi {
@Override
public List<PersonnelsMetaDTO> getMetaData(FtbPersonnelsMetaDataReq info) {
return null;
}
@Override
public Boolean queryCurrMonthDepartStatus(String userId, String tenantId) {
return null;
}
@Override
public Boolean queryCurrMonthDepartStatusByDate(FtbPersonnelsMetaFuctionReq req) {
return null;
}
@Override
public Map<String, Boolean> queryCurrMonthLeave(FtbPersonnelsMetaFuctionReq req) {
return Map.of();
}
@Override
public List<FtbXcCustomFieldVo> queryCustomFiled(FtbXcCustomFieldDto req) {
return List.of();
}
}

View File

@@ -0,0 +1,18 @@
package jnpf.personnels.fallback;
import jnpf.base.ActionResult;
import jnpf.model.personnels.vo.rewardspunishments.FtbPersonnelsRewardsPunishmentApprovalVO;
import jnpf.personnels.FtbPersonnelsRewardsPunishmentsRemoteApi;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class FtbPersonnelsRewardsPunishmentsRemoteFallBackApi implements FtbPersonnelsRewardsPunishmentsRemoteApi {
@Override
public ActionResult<List<FtbPersonnelsRewardsPunishmentApprovalVO>> listApproval(Integer type) {
return ActionResult.fail("OA审批获取奖惩规则降级处理");
}
}

View File

@@ -0,0 +1,107 @@
package jnpf.personnels.fallback;
import jnpf.base.ActionResult;
import jnpf.base.vo.PageListVO;
import jnpf.model.personnels.dto.roster.QueryCompanyAgeDto;
import jnpf.model.personnels.dto.staff.roster.FtbPersonnelsStaffRosterDto;
import jnpf.model.personnels.dto.staff.roster.ShopManagerUserDto;
import jnpf.model.personnels.dto.staff.roster.StaffRosterInfoDto;
import jnpf.model.personnels.req.roster.StaffRosterListReq;
import jnpf.model.personnels.req.roster.StaffRosterReq;
import jnpf.permission.model.user.UserListVO;
import jnpf.permission.vo.user.UserListMatchVO;
import jnpf.personnels.FtbPersonnelsRosterManagerApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.List;
@Component
@Slf4j
public class FtbPersonnelsRosterManagerFallBackApi implements FtbPersonnelsRosterManagerApi {
@Override
public ActionResult updateCompanyAge(String tenantId) {
return null;
}
@Override
public ActionResult<Boolean> bindPhone(String tenantCode, String userId, String phone) {
return null;
}
@Override
public ActionResult<List<QueryCompanyAgeDto>> queryCompanyAge(List<String> userIds, String tenantId) {
return null;
}
@Override
public ActionResult<List<StaffRosterInfoDto>> queryNoSubmitForm(String tenantId) {
return null;
}
@Override
public ActionResult<List<StaffRosterInfoDto>> queryHealthExpire(String tenantId, Long days, Long months) {
return null;
}
@Override
public ActionResult<PageListVO<FtbPersonnelsStaffRosterDto>> pageLists(StaffRosterListReq req) {
return null;
}
@Override
public ActionResult<PageListVO<FtbPersonnelsStaffRosterDto>> pageListsPost(StaffRosterListReq req) {
return null;
}
@Override
public ActionResult<PageListVO<FtbPersonnelsStaffRosterDto>> postWithSalary(StaffRosterListReq req) {
return null;
}
@Override
public List<FtbPersonnelsStaffRosterDto> postWithSalaryNoPage(StaffRosterListReq req) {
return List.of();
}
@Override
public ActionResult<List<FtbPersonnelsStaffRosterDto>> getPersonnelByUserIds(StaffRosterListReq req) {
return null;
}
@Override
public ActionResult<UserListMatchVO> getUserListByMatch(List<String> userIds) {
return null;
}
@Override
public ActionResult<List<FtbPersonnelsStaffRosterDto>> queryDepartUser(@RequestBody List<String> userIds) {
return null;
}
@Override
public ActionResult<ShopManagerUserDto> queryShopManagerUser(String tenantId, List<String> userIds) {
return null;
}
@Override
public ActionResult<List<UserListVO>> timingAlertTrialJob(String tenantId) {
return null;
}
@Override
public List<FtbPersonnelsStaffRosterDto> queryWithUserIds(StaffRosterListReq req) {
return null;
}
@Override
public List<FtbPersonnelsStaffRosterDto> queryWithUserIdsPost(StaffRosterReq req) {
return null;
}
}

View File

@@ -0,0 +1,47 @@
package jnpf.personnels.fallback;
import jnpf.base.ActionResult;
import jnpf.model.personnels.dto.turnover.FtbDepUserDTO;
import jnpf.model.personnels.vo.turnover.FtbPersonnelsTurnoverManagementVO;
import jnpf.permission.vo.v2.user.UserBoundVO;
import jnpf.personnels.FtbPersonnelsTurnoverManagementApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @Title: FtbPersonnelsTurnoverManagementFallBackApi
* @Author: peng.hao
* @create: 2024/2/19 10:38
*/
@Slf4j
@Component
public class FtbPersonnelsTurnoverManagementFallBackApi implements FtbPersonnelsTurnoverManagementApi {
@Override
public ActionResult<String> closeUserAccountRegularlyAfterResignation(String tenantId) {
return null;
}
@Override
public Boolean userHasSignedASeparationAgreement(String userId, Integer flag) {
return null;
}
@Override
public List<FtbPersonnelsTurnoverManagementVO> queryTurnoverList() {
return null;
}
@Override
public List<UserBoundVO> getInformationAboutTheDepartingPerson(FtbDepUserDTO dto) {
return null;
}
@Override
public List<UserBoundVO> getInformationAboutTheDepartingPersonNotToken(FtbDepUserDTO dto) {
return List.of();
}
}

View File

@@ -0,0 +1,22 @@
package jnpf.util.auth;
import io.swagger.v3.oas.annotations.Operation;
import jnpf.util.auth.fallback.V2AuthPermissionApiFallback;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import java.util.List;
/**
* 登录人数据权限-组织范围 API与 FTB 内 {@code V2AuthPermissionUtils#getLoginUserAuthOrganizeIds()} 语义一致)。
* <p>
* 返回值约定:{@code null} 表示全部;空列表表示无权限;非空为组织/门店 id 列表(已排除班组)。
* Feign 降级时抛出异常,不会返回空列表以免误判为无权限(当前暂无正式熔断占位策略)。
*/
@FeignClient(name = "jnpf-ftb", contextId = "v2AuthPermissionApi", path = "/permission/auth", fallbackFactory = V2AuthPermissionApiFallback.class)
public interface V2AuthPermissionApi {
@Operation(summary = "[API] 当前登录人在权限范围内的组织/门店 id 列表(未包裹 ActionResult")
@GetMapping("/login-user-organize-ids")
List<String> getLoginUserAuthOrganizeIds();
}

Some files were not shown because too many files have changed in this diff Show More