""" 字典数据一键初始化脚本 ============================================================= 以本文件内置的 DICT_SEED 为数据源,把所有字典(dict + dict_item)幂等写入数据库 (已存在的字典按 code 跳过)。 用法: python scripts/seed_dict.py 说明: - 一次性初始化工具,数据入库后可删除本文件 - DICT_SEED 是本项目全部数据字典的唯一种子数据源(运行时展示一律走 dict_utils 从字典表读取,勿在业务代码里再硬编码枚举) - 之后请在后台"字典管理"维护字典项(写入会触发 dict_utils 缓存失效,前端即时生效) """ import os import sys # 将项目根加入 sys.path(脚本以 `python scripts/xxx.py` 运行时 cwd 是 scripts/) ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) if ROOT not in sys.path: sys.path.insert(0, ROOT) # ============================================================ # 系统全部数据字典种子定义(幂等初始化:已存在的 code 跳过) # code:字典编码(稳定业务键,如 gender、status、operation_type) # name:字典中文名;note:字典备注(可选) # items:字典项,value 为存储值(写入时统一转为字符串,dict_item.value 是 String 列), # name 为显示文本,顺序即 sort 排序 # ============================================================ DICT_SEED = [ { "code": "gender", "name": "性别", "note": "用户性别", "items": [ {"value": "1", "name": "男"}, {"value": "2", "name": "女"}, {"value": "3", "name": "保密"}, ], }, { "code": "status", "name": "状态", "note": "通用启用状态", "items": [ {"value": "1", "name": "正常"}, {"value": "2", "name": "禁用"}, ], }, { "code": "param_type", "name": "参数类型", "items": [ {"value": "0", "name": "系统参数"}, {"value": "1", "name": "业务参数"}, ], }, { "code": "link_type", "name": "友链类型", "items": [ {"value": "1", "name": "友情链接"}, {"value": "2", "name": "合作伙伴"}, ], }, { "code": "link_form", "name": "友链形式", "items": [ {"value": "1", "name": "文字链接"}, {"value": "2", "name": "图片链接"}, ], }, { "code": "config_item_type", "name": "配置项类型", "note": "配置项输入控件类型", "items": [ {"value": "text", "name": "单行文本"}, {"value": "textarea", "name": "多行文本"}, {"value": "ueditor", "name": "富文本编辑器"}, {"value": "date", "name": "日期"}, {"value": "datetime", "name": "时间"}, {"value": "number", "name": "数字"}, {"value": "select", "name": "下拉框"}, {"value": "radio", "name": "单选框"}, {"value": "checkbox", "name": "复选框"}, {"value": "image", "name": "单张图片"}, {"value": "images", "name": "多张图片"}, {"value": "password", "name": "密码"}, {"value": "icon", "name": "字体图标"}, {"value": "file", "name": "单个文件"}, {"value": "files", "name": "多个文件"}, {"value": "hidden", "name": "隐藏"}, {"value": "readonly", "name": "只读文本"}, ], }, { "code": "city_level", "name": "城市级别", "note": "行政区划级别", "items": [ {"value": "1", "name": "省份"}, {"value": "2", "name": "城市"}, {"value": "3", "name": "县区"}, {"value": "4", "name": "街道"}, ], }, { "code": "notice_type", "name": "通知类型", "items": [ {"value": "1", "name": "通知"}, {"value": "2", "name": "公告"}, ], }, { "code": "operation_source", "name": "操作日志来源", "items": [ {"value": "0", "name": "后台系统"}, {"value": "1", "name": "手机站"}, {"value": "2", "name": "客户端"}, {"value": "3", "name": "其他"}, ], }, { "code": "operation_type", "name": "操作日志类型", "items": [ {"value": "1", "name": "登录"}, {"value": "2", "name": "退出"}, {"value": "3", "name": "新增"}, {"value": "4", "name": "修改"}, {"value": "5", "name": "删除"}, {"value": "6", "name": "查询"}, {"value": "7", "name": "导出"}, {"value": "8", "name": "导入"}, {"value": "9", "name": "提交"}, {"value": "10", "name": "撤销"}, {"value": "11", "name": "审核"}, {"value": "12", "name": "强退"}, {"value": "13", "name": "开账号"}, {"value": "14", "name": "清空"}, {"value": "15", "name": "授权"}, {"value": "16", "name": "缓存"}, {"value": "17", "name": "生成代码"}, {"value": "18", "name": "其他"}, ], }, { "code": "login_type", "name": "登录日志类型", "items": [ {"value": "1", "name": "登录"}, {"value": "2", "name": "退出"}, ], }, { "code": "article_status", "name": "文章状态", "items": [ {"value": "0", "name": "正常"}, {"value": "1", "name": "下架"}, ], }, { "code": "job_log_status", "name": "任务日志状态", "note": "定时任务执行状态", "items": [ {"value": "0", "name": "正常"}, {"value": "1", "name": "失败"}, ], }, { "code": "job_status", "name": "任务状态", "note": "定时任务状态", "items": [ {"value": "0", "name": "未发布"}, {"value": "1", "name": "运行中"}, {"value": "2", "name": "暂停"}, {"value": "3", "name": "删除"}, ], }, { "code": "job_execute_policy", "name": "执行策略", "note": "定时任务执行策略", "items": [ {"value": "1", "name": "立即执行"}, {"value": "2", "name": "执行一次"}, {"value": "3", "name": "放弃执行"}, ], }, ] def seed_dict(app) -> int: """将 DICT_SEED 幂等写入 app 绑定的数据库,返回新增字典数(可测试)。""" from src.core.database import db from src.modules.dictionary import dict_utils from src.modules.dictionary.dict.repository import DictRepository from src.modules.dictionary.dict_item.repository import DictItemRepository created = 0 with app.app_context(): for sort, spec in enumerate(DICT_SEED, 1): if DictRepository.first_by({"code": spec["code"]}): print(f" [skip] {spec['code']}(已存在)") continue dict_obj = DictRepository.create( name=spec["name"], code=spec["code"], note=spec.get("note", ""), sort=sort, create_user="system", ) for idx, item in enumerate(spec["items"], 1): DictItemRepository.create( dict_id=dict_obj.id, name=item["name"], value=str(item["value"]), sort=item.get("sort", idx), create_user="system", ) db.session.commit() created += 1 print(f" [ok] {spec['code']}({len(spec['items'])} 项)") # 失效取值缓存,保证后续读取走新数据 dict_utils.clear_cache() return created def main(): from src.app import create_app print(f"开始初始化字典数据(共 {len(DICT_SEED)} 个字典)...") created = seed_dict(create_app()) print(f"完成:新增 {created} 个字典,跳过 {len(DICT_SEED) - created} 个已存在") if __name__ == "__main__": main()