业务员修改物流单号时PUT /api/orders/{id}/tracking返回403,
根因是salesman角色缺少order:update权限码。在DEFAULT_ROLE_PERMISSIONS、
DEFAULT_ROLE_MENU_CODES和DEFAULT_MENUS三处同步补全。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
232 lines
16 KiB
Python
232 lines
16 KiB
Python
"""
|
||
系统引导数据定义模块。
|
||
|
||
职责:
|
||
定义系统首次初始化时需要写入数据库的基础数据,包括默认角色、系统配置、
|
||
产品分类、菜单权限、管理员账号以及角色-菜单映射关系。
|
||
这些数据在系统启动的 bootstrap 阶段被写入数据库,作为系统运行的基础。
|
||
|
||
依赖:
|
||
本模块为纯数据定义模块,无外部依赖。
|
||
|
||
被引用方:
|
||
- bootstrap_data.py 脚本:系统初始化时读取并写入数据库
|
||
- ConfigService:读取 DEFAULT_CONFIGS 作为配置回退默认值
|
||
"""
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# 默认角色列表
|
||
# ---------------------------------------------------------------------------
|
||
|
||
DEFAULT_ROLES = [
|
||
{"role_name": "管理员", "role_code": "admin", "status": 1, "remark": "系统管理"},
|
||
{"role_name": "业务员", "role_code": "salesman", "status": 1, "remark": "录单和本人订单"},
|
||
{"role_name": "管理层", "role_code": "manager", "status": 1, "remark": "审批和经营数据"},
|
||
{"role_name": "司机", "role_code": "driver", "status": 1, "remark": "司机任务执行"},
|
||
{"role_name": "会计", "role_code": "kuaiji", "status": 1, "remark": "财务和报表"},
|
||
{"role_name": "物流", "role_code": "wuliu", "status": 1, "remark": "物流管理"},
|
||
]
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# 默认系统配置列表
|
||
# ---------------------------------------------------------------------------
|
||
|
||
DEFAULT_CONFIGS = [
|
||
{"config_key": "arrears_generate_mode", "config_value": "pending_logistics", "config_name": "欠款生成模式", "remark": "shipped=发货后记账,pending_logistics=待绑定物流单号后记账", "status": 1},
|
||
{"config_key": "arrears_settlement_start_type", "config_value": "order_date", "config_name": "欠款起算节点", "remark": "order_date=订单日期,delivery_date=发货日期,reconciliation_date=对账日期", "status": 1},
|
||
{"config_key": "arrears_overdue_days", "config_value": "30", "config_name": "欠款超期天数", "remark": "超过该天数未结算触发欠款提醒", "status": 1},
|
||
{"config_key": "logistics_timeout_hours", "config_value": "48", "config_name": "物流超时小时数", "remark": "首个物流节点超过该小时数无流转提醒", "status": 1},
|
||
{"config_key": "inactive_customer_days", "config_value": "90", "config_name": "沉默客户周期", "remark": "超过该天数未下单触发检查", "status": 1},
|
||
{"config_key": "inactive_customer_amount_threshold", "config_value": "1000", "config_name": "沉默客户金额阈值", "remark": "低于该金额不提醒", "status": 1},
|
||
{"config_key": "reminder_method", "config_value": "system", "config_name": "提醒方式", "remark": "system=系统通知,wechat=微信订阅消息,sms=短信", "status": 1},
|
||
{"config_key": "profit_alert_threshold", "config_value": "0", "config_name": "利润预警阈值", "remark": "利润率低于该值时审批页面标红预警,0=不预警", "status": 1},
|
||
{"config_key": "allow_cancel_statuses", "config_value": "draft,pending_approve,approved,pending_driver,accepted,picked_up,pending_logistics,in_transit,shipped", "config_name": "允许取消的订单状态", "remark": "逗号分隔的状态编码列表", "status": 1},
|
||
{"config_key": "report_category_mapping", "config_value": "{}", "config_name": "报表分类映射", "remark": "按产品分类配置统计口径", "status": 1},
|
||
{"config_key": "logistics_trace_provider", "config_value": "internal", "config_name": "物流轨迹服务商", "remark": "internal=内置,kuaidi100或kdniao=快递100", "status": 1},
|
||
{"config_key": "wechat_template_order_status", "config_value": "TkCDtUd1d2MPzMMy_QwvaoHxvweBY-uA9p3jk3nsKi0", "config_name": "微信模板-订单状态变更", "remark": "微信小程序订阅消息模板ID", "status": 1},
|
||
{"config_key": "wechat_template_approval", "config_value": "xNlOt-_6jMTh5VKf9F_pX4aMtwpjXZKUBBTp8QtzTag", "config_name": "微信模板-审批通知", "remark": "微信小程序订阅消息模板ID", "status": 1},
|
||
{"config_key": "wechat_template_task_assigned", "config_value": "uzivHUxL1A3cBguMvC6HDO4aXqvmCV8X3o538SpDEX4", "config_name": "微信模板-任务分配", "remark": "微信小程序订阅消息模板ID", "status": 1},
|
||
{"config_key": "wechat_template_logistics_timeout", "config_value": "1NtPbIS_LtmsJhl4V4V3poWO_EZYYFNbKoLzO1TLTDc", "config_name": "微信模板-物流超时", "remark": "微信小程序订阅消息模板ID", "status": 1},
|
||
{"config_key": "wechat_template_arrears", "config_value": "ulYRf4HgTXNWYSqT0KYVKJiHnG19_12tjcDXMYD2kHo", "config_name": "微信模板-欠款提醒", "remark": "微信小程序订阅消息模板ID", "status": 1},
|
||
{"config_key": "wechat_template_inactive_customer", "config_value": "pWYFYbZNJvnOGD-4ycNf8zxmseIiuogFAXa9biVscBc", "config_name": "微信模板-沉默客户", "remark": "微信小程序订阅消息模板ID", "status": 1},
|
||
{"config_key": "wechat_sa_template_order_status", "config_value": "", "config_name": "服务号模板-订单状态变更", "remark": "微信服务号模板消息模板ID", "status": 1},
|
||
{"config_key": "wechat_sa_template_approval", "config_value": "", "config_name": "服务号模板-审批通知", "remark": "微信服务号模板消息模板ID", "status": 1},
|
||
{"config_key": "wechat_sa_template_task_assigned", "config_value": "", "config_name": "服务号模板-任务分配", "remark": "微信服务号模板消息模板ID", "status": 1},
|
||
{"config_key": "wechat_sa_template_logistics_timeout", "config_value": "", "config_name": "服务号模板-物流超时", "remark": "微信服务号模板消息模板ID", "status": 1},
|
||
{"config_key": "wechat_sa_template_arrears", "config_value": "", "config_name": "服务号模板-欠款提醒", "remark": "微信服务号模板消息模板ID", "status": 1},
|
||
{"config_key": "wechat_sa_template_inactive_customer", "config_value": "", "config_name": "服务号模板-沉默客户", "remark": "微信服务号模板消息模板ID", "status": 1},
|
||
{"config_key": "payment_channels", "config_value": '[{"name":"现金","is_ecommerce":false},{"name":"银行转账","is_ecommerce":false},{"name":"微信","is_ecommerce":false},{"name":"支付宝","is_ecommerce":false},{"name":"月结","is_ecommerce":false},{"name":"淘宝","is_ecommerce":true},{"name":"京东","is_ecommerce":true},{"name":"拼多多","is_ecommerce":true},{"name":"抖音","is_ecommerce":true}]', "config_name": "收款渠道配置", "remark": "JSON数组,每个渠道包含name和is_ecommerce字段", "status": 1},
|
||
]
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# 默认产品分类列表
|
||
# ---------------------------------------------------------------------------
|
||
|
||
DEFAULT_CATEGORIES = [
|
||
{"category_name": "工业品", "category_code": "industry", "sort_no": 1, "status": 1, "remark": "默认分类"},
|
||
{"category_name": "日用品", "category_code": "daily", "sort_no": 2, "status": 1, "remark": "默认分类"},
|
||
]
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# 默认菜单及权限列表
|
||
# 包含页面菜单(page)和按钮权限(button)两类,
|
||
# 通过 parent_id 建立父子层级关系。
|
||
# 仅包含 web-admin 后台管理系统的页面菜单。
|
||
# ---------------------------------------------------------------------------
|
||
|
||
DEFAULT_MENUS = [
|
||
# 工作台
|
||
{"id": 1, "parent_id": 0, "menu_name": "后台首页", "menu_path": "/dashboard", "menu_type": "page", "permission_code": "dashboard:view", "icon": "dashboard", "sort_no": 1, "status": 1},
|
||
|
||
# 主数据
|
||
{"id": 2, "parent_id": 0, "menu_name": "客户管理", "menu_path": "/customers", "menu_type": "page", "permission_code": "customer:list", "icon": "customers", "sort_no": 2, "status": 1},
|
||
{"id": 3, "parent_id": 0, "menu_name": "基础资料", "menu_path": "/master-data", "menu_type": "page", "permission_code": "master-data:list", "icon": "master-data", "sort_no": 3, "status": 1},
|
||
{"id": 4, "parent_id": 0, "menu_name": "定价规则", "menu_path": "/pricing-rules", "menu_type": "page", "permission_code": "pricing-rules:view", "icon": "pricing-rules", "sort_no": 4, "status": 1},
|
||
|
||
# 订单与审批
|
||
{"id": 5, "parent_id": 0, "menu_name": "订单中心", "menu_path": "/orders", "menu_type": "page", "permission_code": "order:list", "icon": "orders", "sort_no": 5, "status": 1},
|
||
{"id": 6, "parent_id": 0, "menu_name": "创建订单", "menu_path": "/orders/create", "menu_type": "page", "permission_code": "order:create", "icon": "order-create", "sort_no": 6, "status": 1},
|
||
{"id": 7, "parent_id": 0, "menu_name": "批量匹配物流", "menu_path": "/orders/batch-match", "menu_type": "page", "permission_code": "order:batch-match", "icon": "batch-match", "sort_no": 7, "status": 1},
|
||
{"id": 8, "parent_id": 0, "menu_name": "提醒中心", "menu_path": "/reminders", "menu_type": "page", "permission_code": "reminder:list", "icon": "reminder", "sort_no": 8, "status": 1},
|
||
|
||
# 配置与权限
|
||
{"id": 9, "parent_id": 0, "menu_name": "配置管理", "menu_path": "/config", "menu_type": "page", "permission_code": "config:view", "icon": "config", "sort_no": 9, "status": 1},
|
||
{"id": 10, "parent_id": 0, "menu_name": "权限与审计", "menu_path": "/audit", "menu_type": "page", "permission_code": "audit:view", "icon": "audit", "sort_no": 10, "status": 1},
|
||
{"id": 11, "parent_id": 0, "menu_name": "系统管理", "menu_path": "/system", "menu_type": "page", "permission_code": "system:view", "icon": "system", "sort_no": 11, "status": 1},
|
||
|
||
# 报表
|
||
{"id": 12, "parent_id": 0, "menu_name": "报表统计", "menu_path": "/reports/performance", "menu_type": "page", "permission_code": "report:performance:view", "icon": "report", "sort_no": 12, "status": 1},
|
||
{"id": 13, "parent_id": 0, "menu_name": "报表核对", "menu_path": "/reports/audit", "menu_type": "page", "permission_code": "report:audit:view", "icon": "report-audit", "sort_no": 13, "status": 1},
|
||
|
||
# AI 功能
|
||
{"id": 14, "parent_id": 0, "menu_name": "AI识别", "menu_path": "/ai-recognition", "menu_type": "page", "permission_code": "ai:recognize", "icon": "ai", "sort_no": 14, "status": 1},
|
||
|
||
# 按钮权限 - 订单相关
|
||
{"id": 20, "parent_id": 5, "menu_name": "提交审核", "menu_path": "", "menu_type": "button", "permission_code": "order:submit", "icon": "", "sort_no": 20, "status": 1},
|
||
{"id": 21, "parent_id": 5, "menu_name": "取消审批", "menu_path": "", "menu_type": "button", "permission_code": "order:cancel-approve", "icon": "", "sort_no": 21, "status": 1},
|
||
{"id": 24, "parent_id": 5, "menu_name": "订单更新", "menu_path": "", "menu_type": "button", "permission_code": "order:update", "icon": "", "sort_no": 24, "status": 1},
|
||
|
||
# 按钮权限 - 基础资料
|
||
{"id": 22, "parent_id": 3, "menu_name": "定价规则编辑", "menu_path": "", "menu_type": "button", "permission_code": "master-data:update", "icon": "", "sort_no": 22, "status": 1},
|
||
|
||
# 按钮权限 - 报表
|
||
{"id": 23, "parent_id": 12, "menu_name": "导出业绩报表", "menu_path": "", "menu_type": "button", "permission_code": "report:performance:export", "icon": "", "sort_no": 23, "status": 1},
|
||
|
||
# 按钮权限 - AI
|
||
{"id": 24, "parent_id": 14, "menu_name": "AI结果修正", "menu_path": "", "menu_type": "button", "permission_code": "ai:correct", "icon": "", "sort_no": 24, "status": 1},
|
||
{"id": 25, "parent_id": 14, "menu_name": "AI订单解析", "menu_path": "", "menu_type": "button", "permission_code": "ai:parse-order", "icon": "", "sort_no": 25, "status": 1},
|
||
|
||
# 按钮权限 - 系统管理
|
||
{"id": 30, "parent_id": 11, "menu_name": "用户列表", "menu_path": "", "menu_type": "button", "permission_code": "system:user:list", "icon": "", "sort_no": 30, "status": 1},
|
||
{"id": 31, "parent_id": 11, "menu_name": "角色管理", "menu_path": "", "menu_type": "button", "permission_code": "system:role:list", "icon": "", "sort_no": 31, "status": 1},
|
||
{"id": 32, "parent_id": 11, "menu_name": "菜单管理", "menu_path": "", "menu_type": "button", "permission_code": "system:menu:list", "icon": "", "sort_no": 32, "status": 1},
|
||
{"id": 33, "parent_id": 11, "menu_name": "用户新增", "menu_path": "", "menu_type": "button", "permission_code": "system:user:create", "icon": "", "sort_no": 33, "status": 1},
|
||
{"id": 34, "parent_id": 11, "menu_name": "用户编辑", "menu_path": "", "menu_type": "button", "permission_code": "system:user:update", "icon": "", "sort_no": 34, "status": 1},
|
||
{"id": 35, "parent_id": 11, "menu_name": "用户重置密码", "menu_path": "", "menu_type": "button", "permission_code": "system:user:reset-password", "icon": "", "sort_no": 35, "status": 1},
|
||
{"id": 36, "parent_id": 11, "menu_name": "角色新增", "menu_path": "", "menu_type": "button", "permission_code": "system:role:create", "icon": "", "sort_no": 36, "status": 1},
|
||
{"id": 37, "parent_id": 11, "menu_name": "角色编辑", "menu_path": "", "menu_type": "button", "permission_code": "system:role:update", "icon": "", "sort_no": 37, "status": 1},
|
||
{"id": 38, "parent_id": 11, "menu_name": "角色授权", "menu_path": "", "menu_type": "button", "permission_code": "system:role:assign-menus", "icon": "", "sort_no": 38, "status": 1},
|
||
{"id": 39, "parent_id": 11, "menu_name": "菜单新增", "menu_path": "", "menu_type": "button", "permission_code": "system:menu:create", "icon": "", "sort_no": 39, "status": 1},
|
||
{"id": 40, "parent_id": 11, "menu_name": "菜单编辑", "menu_path": "", "menu_type": "button", "permission_code": "system:menu:update", "icon": "", "sort_no": 40, "status": 1},
|
||
]
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# 默认管理员账号
|
||
# ---------------------------------------------------------------------------
|
||
|
||
DEFAULT_ADMIN_USER = {
|
||
"username": "admin01",
|
||
"real_name": "系统管理员",
|
||
"mobile": "13900000001",
|
||
"role_id": 1,
|
||
"status": 1,
|
||
}
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# 默认业务员账号
|
||
# ---------------------------------------------------------------------------
|
||
|
||
DEFAULT_SALES_USER = {
|
||
"username": "sales01",
|
||
"real_name": "业务员A",
|
||
"mobile": "13800000002",
|
||
"role_id": 2,
|
||
"status": 1,
|
||
}
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# 角色-菜单权限编码映射
|
||
# 定义每个角色拥有的权限编码列表,bootstrap 阶段用于初始化角色授权关系。
|
||
# ---------------------------------------------------------------------------
|
||
|
||
DEFAULT_ROLE_MENU_CODES = {
|
||
"admin": [item["permission_code"] for item in DEFAULT_MENUS],
|
||
"salesman": [
|
||
"order:list",
|
||
"order:create",
|
||
"order:submit",
|
||
"order:update",
|
||
"customer:list",
|
||
"reminder:list",
|
||
"ai:parse-order",
|
||
"logistics:trace:list",
|
||
],
|
||
"manager": [
|
||
"order:list",
|
||
"order:create",
|
||
"order:submit",
|
||
"order:cancel-approve",
|
||
"customer:list",
|
||
"reminder:list",
|
||
"report:performance:view",
|
||
"report:performance:export",
|
||
"ai:recognize",
|
||
"ai:correct",
|
||
"ai:parse-order",
|
||
],
|
||
"driver": [],
|
||
"kuaiji": [
|
||
"dashboard:view",
|
||
"order:list",
|
||
"customer:list",
|
||
"report:performance:view",
|
||
"report:performance:export",
|
||
"report:audit:view",
|
||
"config:view",
|
||
],
|
||
"wuliu": [
|
||
"dashboard:view",
|
||
"order:list",
|
||
"order:create",
|
||
"order:batch-match",
|
||
"customer:list",
|
||
"ai:parse-order",
|
||
"reminder:list",
|
||
"config:view",
|
||
],
|
||
}
|
||
|
||
|
||
def build_bootstrap_summary() -> dict:
|
||
"""汇总所有引导数据,返回一个完整的 bootstrap 数据包。
|
||
|
||
将默认角色、系统配置、产品分类、菜单权限、角色-菜单映射和管理员账号
|
||
整合到一个字典中,供 bootstrap 脚本或系统初始化流程一次性写入数据库。
|
||
|
||
返回:
|
||
dict: 包含 roles、configs、categories、menus、role_menu_codes、
|
||
admin_user 六个键的字典
|
||
|
||
被调用方:
|
||
- bootstrap_data.py 脚本(系统初始化时调用)
|
||
"""
|
||
return {
|
||
"roles": DEFAULT_ROLES,
|
||
"configs": DEFAULT_CONFIGS,
|
||
"categories": DEFAULT_CATEGORIES,
|
||
"menus": DEFAULT_MENUS,
|
||
"role_menu_codes": DEFAULT_ROLE_MENU_CODES,
|
||
"admin_user": DEFAULT_ADMIN_USER,
|
||
"sales_user": DEFAULT_SALES_USER,
|
||
}
|