# +====================================================================== # | DjangoAdmin 企业数字化开发平台 [ 赋能开发者,助力企业发展 ] # +---------------------------------------------------------------------- # | Copyright (c) 2021-2026 小蚂蚁云团队 版权所有 # +---------------------------------------------------------------------- # | 开源协议: Apache-2.0 # | 重要声明: 未经书面许可,不得移除或修改本框架相关版权标识。 # +---------------------------------------------------------------------- # | 官方网站: https://www.djangoadmin.cn # +---------------------------------------------------------------------- # | 研发团队: 小蚂蚁云团队 荣誉出品 # +====================================================================== # | 版权和免责声明: # | 一、知识产权声明 # | 本团队对该软件框架产品(以下简称“本产品”)拥有完整知识产权,包括但不限于商标权、专利权、 # | 著作权、商业秘密等。前述权利均受中华人民共和国及相关国际法律法规保护。未经本团队书面授权, # | 任何个人或单位不得基于本产品本身申请任何形式的知识产权。 # | 二、使用限制与禁止条款 # | 您理解并同意,禁止将本产品用于以下任何行为: # | 1. 任何违反中华人民共和国法律法规的用途; # | 2. 任何侵害他人合法权益(包括但不限于人身权、财产权、知识产权等)的行为; # | 3. 任何危害国家安全、公共利益及社会道德风尚的行为。 # | 三、责任豁免 # | 因使用本产品而产生的任何损失或法律纠纷(包括但不限于直接损失、间接损失、附带损失、衍生损失 # | 以及因违约、侵权等引发的责任),本团队均不承担任何法律责任。若因违规使用本产品导致任何第三 # | 方提起索赔或行政机关进行调查,您应独立承担全部责任。 # | 四、违约与法律责任 # | 如发现任何违反本声明的行为,本团队有权: # | 1. 无条件配合公安机关及其他有权机关的调查取证工作; # | 2. 依法追究相关方的民事责任,并要求赔偿全部损失; # | 3. 保留进一步采取刑事控告等法律措施的权利。 # | 五、许可范围说明 # | 1、被授权方应视本产品源代码为核心机密信息,负有最高标准的保密与保管义务。禁止以任何形式(包 # | 括但不限于直接或间接的分享、复制、传播、分发、转售、出租、开源、反向工程、反编译、反汇编或通 # | 过网络服务提供给任何第三方)泄露、披露或处置源代码的全部或部分内容。任何未经授权的复制、使用、 # | 传播行为均构成对本团队知识产权的严重侵权,本团队有权依法追究其全部法律责任,并要求赔偿因此造 # | 成的一切经济损失及商誉损害。 # | 2、本产品仅限于公司或个人在法律允许范围内,用于内部且合规的软件产品研发。具体权利义务以《软件 # | 许可协议》附件为准。 # +====================================================================== # +====================================================================== # | 模块: 业务字典数据初始化脚本 # | 说明: 幂等写入业务字典(dict + dict_item),按字典编码判重 # +====================================================================== """ 业务字典数据初始化脚本 ============================================================= 幂等写入业务字典(dict + dict_item):按字典编码(code)判重, 已存在则跳过、不覆盖现有数据;适合全新安装或现有库增量补齐。 字典格式(code/name/note/items),字典排序与字典项排序由列表顺序自动生成: DICT_SEED = [ { "code": "gender", "name": "性别", "note": "用户性别", "items": [ {"value": "1", "name": "男"}, {"value": "2", "name": "女"}, ], }, ] 注意:code 必须与业务代码中 get_dict_map / get_dict_label / serialize_maps 引用的编码一致(见 src/utils/dict_util.py),改 code 需同步改业务引用。 用法: python scripts/seed_dict.py # 使用 .env 中的数据库配置 python scripts/seed_dict.py --dry-run # 只打印将写入的字典,不落库 """ import argparse import os import sys sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "src")) # Windows 控制台默认 GBK(cp936):把 stdout/stderr 切到 UTF-8,避免中文打印乱码/崩溃 if sys.stdout and hasattr(sys.stdout, 'reconfigure'): sys.stdout.reconfigure(encoding='utf-8') sys.stderr.reconfigure(encoding='utf-8') # ============================================================ # 业务字典种子数据 # ============================================================ DICT_SEED = [ { "code": "gender", "name": "性别", "note": "用户性别", "items": [ {"value": "1", "name": "男"}, {"value": "2", "name": "女"}, {"value": "3", "name": "保密"}, ], }, { "code": "dept_type", "name": "部门类型", "note": "部门层级类型", "items": [ {"value": "1", "name": "公司"}, {"value": "2", "name": "子公司"}, {"value": "3", "name": "部门"}, {"value": "4", "name": "小组"}, ], }, { "code": "article_status", "name": "文章状态", "note": "文章上下架状态", "items": [ {"value": "0", "name": "正常"}, {"value": "1", "name": "下架"}, ], }, { "code": "notice_source", "name": "通知来源", "note": "通知公告来源", "items": [ {"value": "1", "name": "官方平台"}, {"value": "2", "name": "开源中国"}, {"value": "3", "name": "CSDN官方"}, {"value": "4", "name": "新浪微博"}, ], }, { "code": "log_type", "name": "日志类型", "note": "登录日志类型", "items": [ {"value": "1", "name": "登录"}, {"value": "2", "name": "退出"}, ], }, { "code": "login_source", "name": "登录来源", "note": "登录入口来源", "items": [ {"value": "0", "name": "后台"}, {"value": "1", "name": "前台"}, ], }, { "code": "login_status", "name": "登录状态", "note": "登录日志状态", "items": [ {"value": "0", "name": "正常"}, {"value": "1", "name": "异常"}, ], }, { "code": "operation_source", "name": "操作日志来源", "note": "操作日志来源", "items": [ {"value": "0", "name": "后台"}, {"value": "1", "name": "前台"}, ], }, { "code": "operation_status", "name": "操作日志状态", "note": "操作日志状态", "items": [ {"value": "0", "name": "正常"}, {"value": "1", "name": "异常"}, ], }, { "code": "operation_type", "name": "操作日志类型", "note": "操作日志类型(由 URL 路径自动推断)", "items": [ {"value": "0", "name": "其它"}, {"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": "开账号"}, ], }, { "code": "param_type", "name": "参数类型", "note": "参数分类", "items": [ {"value": "0", "name": "系统"}, {"value": "1", "name": "业务"}, ], }, { "code": "param_status", "name": "参数状态", "note": "参数启用状态", "items": [ {"value": "1", "name": "正常"}, {"value": "2", "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": "放弃执行"}, ], }, { "code": "job_log_status", "name": "任务日志状态", "note": "任务执行结果状态", "items": [ {"value": "0", "name": "正常"}, {"value": "1", "name": "失败"}, ], }, { "code": "link_type", "name": "友链类型", "note": "友链分类", "items": [ {"value": "1", "name": "友情链接"}, {"value": "2", "name": "合作伙伴"}, ], }, { "code": "link_platform", "name": "友链投放平台", "note": "友链投放平台", "items": [ {"value": "1", "name": "PC站"}, {"value": "2", "name": "WAP站"}, {"value": "3", "name": "微信小程序"}, {"value": "4", "name": "APP应用"}, ], }, { "code": "link_form", "name": "友链形式", "note": "友链展示形式", "items": [ {"value": "1", "name": "文字链接"}, {"value": "2", "name": "图片链接"}, ], }, { "code": "city_level", "name": "城市级别", "note": "行政区划级别", "items": [ {"value": "1", "name": "省份"}, {"value": "2", "name": "城市"}, {"value": "3", "name": "县区"}, {"value": "4", "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": "只读文本"}, ], }, ] # ============================================================ # 主入口 # ============================================================ def main(): parser = argparse.ArgumentParser(description="初始化业务字典数据") parser.add_argument("--dry-run", action="store_true", help="仅打印计划,不写库") args = parser.parse_args() from core.database import SessionLocal from modules.dictionary.dict.models import Dict from modules.dictionary.dict_item.models import DictItem db = SessionLocal() added = skipped = 0 try: for idx, d in enumerate(DICT_SEED): code = d["code"] exists = db.query(Dict).filter(Dict.code == code, Dict.is_delete == 0).first() if exists: skipped += 1 continue if args.dry_run: print(f"[DRY-RUN] 将新增字典: {code}({d['name']},{len(d['items'])} 项)") continue dict_obj = Dict(name=d["name"], code=code, sort=(idx + 1) * 5, note=d.get("note", "")) db.add(dict_obj) db.flush() # 获取自增 id 供字典项外键引用 for i, item in enumerate(d["items"]): db.add(DictItem( name=item["name"], value=item["value"], dict_id=dict_obj.id, sort=(i + 1) * 5, note='', )) added += 1 db.commit() if not args.dry_run: print(f"done: added={added} dicts, skipped={skipped}(已存在)") except Exception: db.rollback() raise finally: db.close() if __name__ == "__main__": main()