chore: 年度リストを昇順に変更
This commit is contained in:
@@ -29,6 +29,10 @@ class CallbackRequest(BaseModel):
|
||||
state: str
|
||||
|
||||
|
||||
class ApplyRequest(BaseModel):
|
||||
proc_id: str # 16文字の手続識別子
|
||||
|
||||
|
||||
class ConfigRequest(BaseModel):
|
||||
software_id: str
|
||||
api_key: str
|
||||
@@ -245,6 +249,18 @@ async def save_config(req: ConfigRequest):
|
||||
return {"message": "設定を保存しました"}
|
||||
|
||||
|
||||
@router.get("/config-info")
|
||||
async def get_config_info():
|
||||
"""現在の設定情報(APIキーは非表示)を返す"""
|
||||
import os
|
||||
cfg = egov_api.load_api_config()
|
||||
return {
|
||||
"software_id": cfg.get("client_id", ""),
|
||||
"redirect_uri": cfg.get("redirect_uri", ""),
|
||||
"environment": os.environ.get("EGOV_ENV", "production"),
|
||||
}
|
||||
|
||||
|
||||
@router.get("/auth-url")
|
||||
async def get_auth_url():
|
||||
"""OAuth2 + PKCE 認可 URL を生成して返す"""
|
||||
@@ -370,3 +386,154 @@ async def debug_page():
|
||||
return {"browser_state": state.status, **diag}
|
||||
except Exception as e:
|
||||
return {"error": str(e), "status": state.status}
|
||||
|
||||
|
||||
# ── 申請書作成・一覧 エンドポイント ────────────────────────────
|
||||
|
||||
async def _ensure_valid_token() -> str:
|
||||
"""有効なアクセストークンを返す(期限切れ時は自動更新)"""
|
||||
cfg = egov_api.load_api_config()
|
||||
if not cfg["client_id"] or not cfg["client_secret"]:
|
||||
raise HTTPException(status_code=400, detail="e-Gov API 資格情報が未設定です")
|
||||
|
||||
# メモリが空の場合はファイルから expires_at を正しく復元
|
||||
if not state.access_token:
|
||||
saved = egov_api.load_tokens()
|
||||
if saved.get("access_token"):
|
||||
state.access_token = saved["access_token"]
|
||||
state.refresh_token = saved.get("refresh_token")
|
||||
state.token_expires_at = saved.get("expires_at") # float タイムスタンプをそのまま復元
|
||||
|
||||
# トークンが期限切れ → リフレッシュを試みる
|
||||
if not state.is_token_valid() and state.refresh_token:
|
||||
try:
|
||||
token_resp = await egov_api.refresh_tokens_request(
|
||||
state.refresh_token, cfg["client_id"], cfg["client_secret"]
|
||||
)
|
||||
state.set_tokens(token_resp)
|
||||
egov_api.save_tokens({
|
||||
"access_token": state.access_token,
|
||||
"refresh_token": state.refresh_token,
|
||||
"expires_at": state.token_expires_at,
|
||||
})
|
||||
except Exception as e:
|
||||
state.access_token = None
|
||||
raise HTTPException(
|
||||
status_code=401,
|
||||
detail=f"トークン更新失敗: {e}。再度 GビズIDログイン が必要です。"
|
||||
)
|
||||
|
||||
if not state.access_token:
|
||||
raise HTTPException(status_code=401, detail="認証が必要です。GビズID でログインしてください。")
|
||||
|
||||
if not state.is_token_valid():
|
||||
raise HTTPException(
|
||||
status_code=401,
|
||||
detail="アクセストークンが期限切れです。再度 GビズIDログイン してください。"
|
||||
)
|
||||
|
||||
return state.access_token
|
||||
|
||||
|
||||
@router.post("/test-apply")
|
||||
async def test_apply(req: ApplyRequest):
|
||||
"""
|
||||
テスト申請書作成:スケルトン(ひな形)を取得してそのまま申請送信する。
|
||||
到達番号(arrive_id)を返す。
|
||||
"""
|
||||
import re
|
||||
if not re.fullmatch(r"[A-Za-z0-9]{16}", req.proc_id):
|
||||
raise HTTPException(status_code=400, detail="proc_id は半角英数字16文字です")
|
||||
|
||||
access_token = await _ensure_valid_token()
|
||||
|
||||
# 1. スケルトン取得
|
||||
try:
|
||||
skel_resp = await egov_api.get_procedure_skeleton(access_token, req.proc_id)
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=502, detail=f"スケルトン取得失敗: {e}")
|
||||
|
||||
results = skel_resp.get("results", {})
|
||||
file_data_b64 = results.get("file_data", "")
|
||||
if not file_data_b64:
|
||||
raise HTTPException(status_code=502, detail="スケルトンデータが空です")
|
||||
|
||||
# 2. 申請送信(スケルトンをそのまま送信)
|
||||
# 電子申請手続 → POST /apply(トライアルモード)
|
||||
# 電子送達手続 → POST /post-apply(トライアル非対応のため自動フォールバック)
|
||||
# 電子送達手続の場合は kousei.xml に必須フィールドを埋めてから送信する
|
||||
file_name = f"{req.proc_id}.zip"
|
||||
apply_resp = None
|
||||
api_type = "電子申請"
|
||||
try:
|
||||
apply_resp = await egov_api.submit_apply(
|
||||
access_token, req.proc_id, file_name, file_data_b64, trial=True
|
||||
)
|
||||
except RuntimeError as e:
|
||||
err_str = str(e)
|
||||
if "対象手続ではありません" in err_str or "post-apply" in err_str.lower():
|
||||
# 電子送達利用申込み手続 → kousei.xml 修正 → /post-apply
|
||||
api_type = "電子送達利用申込み"
|
||||
# 公式手続一覧 egov_applapi_testproclist.xlsx より正しい手続名称
|
||||
proc_name = "APIテスト用手続(電子送達関係手続)(通)0001/APIテスト用手続(電子送達関係手続)(通)0001"
|
||||
# スケルトン kousei.xml に必須フィールドを埋める
|
||||
try:
|
||||
modified_file_data = egov_api.modify_skeleton_for_post_apply(
|
||||
file_data_b64=file_data_b64,
|
||||
proc_id=req.proc_id,
|
||||
proc_name=proc_name,
|
||||
uketsuke_kikan_id="100900", # 電子送達関係手続の受付行政機関ID
|
||||
shinsei_shubetsu="新規申請",
|
||||
shimei="テスト タロウ",
|
||||
shimei_furigana="テスト タロウ",
|
||||
yubin="1300022",
|
||||
jusho="東京都墨田区江東橋4丁目31番10号",
|
||||
)
|
||||
except Exception as emx:
|
||||
raise HTTPException(status_code=502, detail=f"スケルトン修正失敗: {emx}")
|
||||
try:
|
||||
apply_resp = await egov_api.submit_post_apply(
|
||||
access_token, req.proc_id, file_name, modified_file_data
|
||||
)
|
||||
except Exception as e2:
|
||||
raise HTTPException(status_code=502, detail=f"電子送達利用申込み失敗: {e2}")
|
||||
else:
|
||||
raise HTTPException(status_code=502, detail=f"申請送信失敗: {err_str}")
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=502, detail=f"申請送信失敗: {e}")
|
||||
|
||||
res = apply_resp.get("results", {})
|
||||
return {
|
||||
"arrive_id": res.get("arrive_id", ""),
|
||||
"arrive_date": res.get("arrive_date", ""),
|
||||
"proc_name": res.get("proc_name", ""),
|
||||
"proc_id": req.proc_id,
|
||||
"api_type": api_type,
|
||||
"raw": res,
|
||||
}
|
||||
|
||||
|
||||
@router.get("/apply-list")
|
||||
async def apply_list():
|
||||
"""申請案件一覧取得"""
|
||||
access_token = await _ensure_valid_token()
|
||||
|
||||
try:
|
||||
resp = await egov_api.get_apply_list(access_token)
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=502, detail=f"申請案件一覧取得失敗: {e}")
|
||||
|
||||
results = resp.get("results", {})
|
||||
apply_list_data = results.get("apply_list", [])
|
||||
|
||||
items = []
|
||||
for item in apply_list_data:
|
||||
items.append({
|
||||
"arrive_id": item.get("arrive_id", ""),
|
||||
"arrive_date": item.get("arrive_date", ""),
|
||||
"proc_id": item.get("proc_id", ""),
|
||||
"proc_name": item.get("proc_name", ""),
|
||||
"status": item.get("status", ""),
|
||||
"sub_status": item.get("sub_status", ""),
|
||||
})
|
||||
return {"apply_list": items, "total": len(items)}
|
||||
|
||||
Reference in New Issue
Block a user