:::tip 用户管理 用户管理是系统的核心模块,属于复杂业务模块。包含用户 CRUD、角色关联、密码加密、行政区划等功能。与简单 CRUD 模块不同,用户管理使用自定义 service 函数。 ::: ## 模块结构 ``` application/user/ ├── models.py # 用户模型 ├── forms.py # 表单验证 ├── services.py # 业务逻辑层(自定义函数) ├── views.py # 视图层 └── urls.py # 路由配置 application/user_role/ ├── models.py # 用户-角色关联模型 ├── services.py # 关联业务逻辑 └── urls.py # 路由配置 ``` ## 用户模型 ```python # application/user/models.py from application.models import BaseModel class User(BaseModel): """用户模型类""" class Meta: db_table = 'django_user' code = models.CharField(max_length=100, default='', verbose_name='用户编码') realname = models.CharField(max_length=150, verbose_name='用户姓名') gender = models.IntegerField(default=1, verbose_name='性别:1-男 2-女 3-保密') avatar = models.CharField(max_length=255, default='', verbose_name='用户头像') mobile = models.CharField(max_length=30, default='', verbose_name='手机号') email = models.CharField(max_length=30, default='', verbose_name='邮箱') dept_id = models.IntegerField(default=0, verbose_name='部门ID') level_id = models.IntegerField(default=0, verbose_name='职级ID') position_id = models.IntegerField(default=0, verbose_name='岗位ID') province_code = models.CharField(max_length=30, default='', verbose_name='省份编码') city_code = models.CharField(max_length=30, default='', verbose_name='城市编码') district_code = models.CharField(max_length=30, default='', verbose_name='县区编码') street_code = models.CharField(max_length=30, default='', verbose_name='街道编码') city_info = models.CharField(max_length=255, null=True, blank=True, verbose_name='省市区信息') address = models.CharField(max_length=255, default='', verbose_name='详细地址') username = models.CharField(max_length=30, null=True, blank=True, verbose_name='用户名') password = models.CharField(max_length=255, null=True, blank=True, verbose_name='密码') salt = models.CharField(max_length=30, null=True, blank=True, verbose_name='加密盐') intro = models.CharField(max_length=255, null=True, blank=True, verbose_name='个人简介') status = models.IntegerField(default=1, verbose_name='状态:1-正常 2-禁用') sort = models.IntegerField(default=0, verbose_name='排序') note = models.CharField(max_length=255, null=True, blank=True, verbose_name='个人备注') ``` ## 密码加密 使用 bcrypt 双重加盐方案,由 `utils/password.py` 提供: ```python # utils/password.py import secrets import bcrypt BCRYPT_ROUNDS = 12 def generate_salt(length=10): """生成随机盐值""" return secrets.token_urlsafe(length)[:length] def encrypt_password(password, salt): """使用 bcrypt 加密密码(外部 salt 双重加盐)""" combined = (password + salt).encode('utf-8') hashed = bcrypt.hashpw(combined, bcrypt.gensalt(rounds=BCRYPT_ROUNDS)) return hashed.decode('utf-8') def verify_password(password, salt, hashed): """验证密码是否正确""" combined = (password + salt).encode('utf-8') return bcrypt.checkpw(combined, hashed.encode('utf-8')) ``` :::tip 双重加盐 密码加密采用双重加盐:外部 salt(存储在 user 表)+ bcrypt 内部 salt。即使数据库泄露,攻击者也无法通过彩虹表破解密码。工作因子 12,单次加密约 250ms。 ::: ## 角色关联 用户与角色通过 `django_user_role` 关联表实现多对多关系: ```python # application/user_role/models.py class UserRole(BaseModel): """用户角色关联模型类""" class Meta: db_table = 'django_user_role' user_id = models.IntegerField(default=0, verbose_name='用户ID') role_id = models.IntegerField(default=0, verbose_name='角色ID') ``` ## 关联数据富化 用户列表和详情需要富化部门、职级、岗位、角色等关联数据: ```python # application/user/services.py def _enrich_user_records(records): """为用户记录补充关联数据""" dept_map = {d.id: d.name for d in Dept.objects.filter(is_delete=False)} level_map = {l.id: l.name for l in Level.objects.filter(is_delete=False)} position_map = {p.id: p.name for p in Position.objects.filter(is_delete=False)} for data in records: data["deptName"] = dept_map.get(data.get("deptId")) data["levelName"] = level_map.get(data.get("levelId")) data["positionName"] = position_map.get(data.get("positionId")) return records ``` ## API 接口 | 接口 | 方法 | 权限节点 | 说明 | |------|------|---------|------| | `/user/page` | GET | `sys:user:page` | 用户分页列表 | | `/user/detail/` | GET | `sys:user:detail` | 用户详情 | | `/user/add` | POST | `sys:user:add` | 新增用户 | | `/user/update` | POST | `sys:user:update` | 编辑用户 | | `/user/delete/` | POST | `sys:user:delete` | 删除用户 | | `/user/status` | POST | `sys:user:status` | 设置状态 | | `/user/resetPwd` | POST | `sys:user:resetPwd` | 重置密码 | :::warning 内置超管保护 用户 ID 为 1 的内置超管账号禁止通过管理接口修改、删除、禁用、重置密码。这些操作会在 service 层提前拦截并返回失败提示。 ::: ## 总结 用户管理模块具备以下特点: ``` 1. 复杂业务:自定义 service 函数,处理关联数据 2. 密码安全:bcrypt 双重加盐,工作因子12 3. 角色关联:多对多关系,通过 user_role 关联表 4. 关联富化:列表/详情补充部门、职级、岗位、角色等展示名称 5. 行政区划:省/市/区/街道四级编码 6. 超管保护:ID=1 账号禁止修改/删除/禁用/重置密码 ```