{"record":{"id":"d8f81a62655b4bbf","repo":"flipped-aurora/gin-vue-admin","slug":"error-d8f81a","errorCode":null,"errorMessage":"主部门必须在归属部门范围内","messagePattern":"主部门必须在归属部门范围内","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/service/system/sys_user.go","lineNumber":269,"sourceCode":"\t\t\tif txErr := tx.Create(&records).Error; txErr != nil {\n\t\t\t\treturn txErr\n\t\t\t}\n\t\t}\n\t\t// 计算主部门\n\t\tpid := primaryDeptId\n\t\tif pid == 0 && len(deptIds) > 0 {\n\t\t\tpid = deptIds[0]\n\t\t}\n\t\tif pid != 0 {\n\t\t\tinSet := false\n\t\t\tfor _, deptId := range deptIds {\n\t\t\t\tif deptId == pid {\n\t\t\t\t\tinSet = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !inSet {\n\t\t\t\treturn errors.New(\"主部门必须在归属部门范围内\")\n\t\t\t}\n\t\t}\n\t\treturn tx.Model(&system.SysUser{}).Where(\"id = ?\", id).Update(\"dept_id\", pid).Error\n\t})\n}\n\n// SetUserPositions 设置用户岗位(多岗位)\nfunc (userService *UserService) SetUserPositions(ctx context.Context, id uint, positionIds []uint) (err error) {\n\treturn global.GVA_DB.WithContext(ctx).Transaction(func(tx *gorm.DB) error {\n\t\tif txErr := tx.Delete(&[]system.SysUserPosition{}, \"sys_user_id = ?\", id).Error; txErr != nil {\n\t\t\treturn txErr\n\t\t}\n\t\tif len(positionIds) > 0 {\n\t\t\trecords := make([]system.SysUserPosition, 0, len(positionIds))\n\t\t\tfor _, positionId := range positionIds {\n\t\t\t\trecords = append(records, system.SysUserPosition{SysUserId: id, SysPositionId: positionId})\n\t\t\t}\n\t\t\tif txErr := tx.Create(&records).Error; txErr != nil {","sourceCodeStart":251,"sourceCodeEnd":287,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/service/system/sys_user.go#L251-L287","documentation":"SetUserDepartments stamps the user's data-permission department (dept_id) with primaryDeptId. The primary department must be inside the deptIds set; if the loop over deptIds finds no match for pid, it returns errors.New(\"主部门必须在归属部门范围内\") before updating.","triggerScenarios":"Calling SetUserDepartments (sys_user.go:269) where primaryDeptId is non-zero but not present in deptIds — e.g. the user's current primary department was removed from the new department selection, or the caller passes a stale primaryDeptId.","commonSituations":"Front end keeping the old primary department checked-out while the user unchecks it in the dept tree; API consumers sending primaryDeptId from cached user data; forgetting to set primaryDeptId semantics (empty means first of set).","solutions":["Set primaryDeptId to one of the ids in deptIds, or pass 0 to let the service default to deptIds[0].","Update the front end so unchecking the primary department clears/resets primaryDeptId.","Ensure deptIds and primaryDeptId come from the same submitted form state, not mixed with cached data."],"exampleFix":"// before\nawait setUserDepartments({ id, deptIds: [2,3], primaryDeptId: 7 }) // 7 not in set\n// after\nawait setUserDepartments({ id, deptIds: [2,3], primaryDeptId: 2 })","handlingStrategy":"validation","validationCode":"if (primaryDeptId && !deptIds.includes(primaryDeptId)) {\n  ElMessage.warning('主部门必须在归属部门范围内'); return\n}","typeGuard":null,"tryCatchPattern":"try {\n  await setUserDepartments({ id, deptIds, primaryDeptId })\n} catch (e) {\n  if (e.message === '主部门必须在归属部门范围内') ElMessage.warning('请选择归属部门内的主部门')\n  else throw e\n}","preventionTips":["In the dept tree UI, prevent unchecking the current primary department without resetting primaryDeptId.","Pass primaryDeptId = 0 to let the backend default to the first dept in the set.","Keep deptIds and primaryDeptId sourced from the same form state."],"tags":["department","data-scope","validation","business-rule"],"backgroundTag":"primary-dept-out-of-range","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}