Files
cmbot/src/services/config_service.py
T
adminandClaude Opus 4.8 f767ec2660 feat: persist template/batch-mode, per-aspect resets, de-dup template actions
§17.1 Preferences persistence:
- Wire the previously-unused config_service; remember and restore the
  last-selected template and last batch mode. main_window loads config,
  distributes initial values, then persists on change (save-on-change).
- template_panel: template_changed signal, select_template,
  current_template_state. queue_panel: set_batch_mode + batch_mode_changed.

§17.2 Independent resets:
- Replace the combined reset and 归零 with per-section 位置/尺寸/旋转 reset
  buttons (quiet ghost styling) that restore only their own aspect to the
  selected template. Size reset changes width/height only, leaving X/Y.

Button de-dup:
- Remove the export panel's 应用为模板 / 重置为模板 — literal duplicates of
  the template panel's 另存为 / 重置为模板. Template actions now live only
  in the template area; the export panel handles output only.

Docs: PRD (6.6/6.9/9/10), architecture (4.12), UI design (7.x/10),
development-rules (6, single-home actions + consistent naming), tasks.md (17).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 17:01:58 +08:00

65 lines
2.2 KiB
Python

import json
import logging
logger = logging.getLogger(__name__)
DEFAULT_CONFIG = {
"output_format": "PNG", # PNG or JPG
"output_quality": 95, # JPG quality 1-95
"output_dir": "", # empty = use app output/ dir
"last_garment_dir": "",
"last_print_dir": "",
"last_template": "", # name of the last-selected template
"last_batch_mode": "full_combo", # BatchMode value of the last-used mode
}
_CONFIG_FILENAME = "app_config.json"
def load_config():
"""
从 JSON 文件加载应用配置。
返回默认配置与文件配置的合并字典。如果配置文件不存在、损坏或无法读取,
函数不会抛出异常,而是记录日志并返回默认配置。
Returns:
dict: 合并后的配置字典
"""
from services.file_service import get_config_path
config_file = get_config_path(_CONFIG_FILENAME)
if not config_file.exists():
logger.info("Config file not found, using defaults: %s", config_file)
return dict(DEFAULT_CONFIG)
try:
with open(str(config_file), encoding="utf-8") as f:
data = json.load(f)
if not isinstance(data, dict):
raise ValueError("Config root is not a JSON object")
merged = dict(DEFAULT_CONFIG)
merged.update(data)
logger.info("Config loaded from %s", config_file)
return merged
except (json.JSONDecodeError, ValueError) as exc:
logger.warning("Config file damaged (%s), using defaults: %s", exc, config_file)
return dict(DEFAULT_CONFIG)
except OSError as exc:
logger.warning("Config file unreadable (%s), using defaults: %s", exc, config_file)
return dict(DEFAULT_CONFIG)
def save_config(data):
"""Save config dict to JSON. Logs error on failure, does not raise."""
from services.file_service import get_config_path
config_file = get_config_path(_CONFIG_FILENAME)
try:
config_file.parent.mkdir(exist_ok=True)
with open(str(config_file), "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
logger.info("Config saved to %s", config_file)
except OSError as exc:
logger.error("Failed to save config to %s: %s", config_file, exc)