Files
query-payslip-default/scripts/service/glossary_service.py
skill-dev 3db196e49d feat: 工资查询助手首版 v1.0.105
基于 skill-template 脚手架开发,包含:
- payroll_config(费率配置,可编辑)+ payslip_snapshots(解析历史,只读)2 张业务表
- 全国默认 + 北上广 4 套费率(社保/公积金/个税起征点/7 级税率表)
- 5 个业务 Action:calculate-payslip-simple / calculate-payslip-full / explain-term / view-config / edit-config
- 个税累计预扣法计算,支持多月历史累加
- 20 个薪资名词库(社保/公积金/个税/全勤/加班费等)
- 完整市场文档(README/TUTORIAL/DEMO/CHANGELOG)
- 296 测试全部通过
2026-09-07 17:02:05 +08:00

96 lines
2.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""名词解释服务。
从 assets/glossary.json 读取词条,按 key/display/category 查询。
不做 LLM 生成,纯静态数据查询。
"""
from __future__ import annotations
import json
from typing import Any, Optional
from util.constants import SKILL_SLUG
from util.logging_config import get_skill_logger
from util.runtime_paths import get_skill_root
log = get_skill_logger()
def _load_glossary() -> list[dict[str, Any]]:
"""从 assets/glossary.json 加载全部词条。"""
glossary_path = get_skill_root() / "assets" / "glossary.json"
try:
with open(glossary_path, "r", encoding="utf-8") as f:
data = json.load(f)
terms = data.get("terms", []) if isinstance(data, dict) else []
return terms if isinstance(terms, list) else []
except (FileNotFoundError, json.JSONDecodeError, OSError):
return []
def explain_term(term: str) -> dict[str, Any]:
"""查询单个名词解释。
支持按 key(精确)或 display(包含)匹配。
未命中返回结构化空(ok=True, found=False)。
"""
log.info("glossary_explain term=%s", term)
terms = _load_glossary()
term_lower = (term or "").strip().lower()
hit: Optional[dict[str, Any]] = None
for t in terms:
if str(t.get("key", "")).lower() == term_lower:
hit = t
break
if term_lower in str(t.get("display", "")).lower():
hit = t
break
if hit is None:
return {
"ok": True,
"skill": SKILL_SLUG,
"found": False,
"term": term,
"explanation": None,
"suggestions": [str(t.get("display", "")) for t in terms[:5]],
}
return {
"ok": True,
"skill": SKILL_SLUG,
"found": True,
"term": term,
"key": hit.get("key"),
"display": hit.get("display"),
"category": hit.get("category"),
"explanation": hit.get("explanation"),
"example": hit.get("example"),
}
def list_terms(category: str | None = None) -> dict[str, Any]:
"""列出全部或按分类的词条。"""
terms = _load_glossary()
if category:
filtered = [t for t in terms if str(t.get("category", "")).lower() == category.lower()]
else:
filtered = terms
return {
"ok": True,
"skill": SKILL_SLUG,
"count": len(filtered),
"categories": sorted({str(t.get("category", "")) for t in terms}),
"terms": [
{
"key": t.get("key"),
"display": t.get("display"),
"category": t.get("category"),
"explanation": t.get("explanation"),
"example": t.get("example"),
}
for t in filtered
],
}