This commit is contained in:
@@ -0,0 +1,282 @@
|
||||
"""
|
||||
业务字典数据初始化脚本
|
||||
=============================================================
|
||||
|
||||
幂等写入业务字典(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/common/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": "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()
|
||||
Reference in New Issue
Block a user