# 用户统计数据配置 JSON 结构说明 ## 概述 `user_statistics_configs` 表的 `config_json` 字段用于存储动态统计配置,包含三个主要部分:数据来源、条件设置、统计方式。 ## JSON 结构 ```json { "data_source": { "main_model": "user|company|course_sign|course|course_type", "relations": ["user", "company", "course_sign", "course", "course_type"] }, "conditions": { "logic": "and|or", "items": [ { "key": "字段名", "operator": "操作类型", "value": "值" } ] }, "statistics": { "type": "sum|max|min|count|count_distinct", "field": "统计字段(sum/max/min 时使用,可选)", "distinct_field": "去重字段(count_distinct 时使用,可选)", "group_by": "分组字段(可选,不设置则不分组)", "order_by": { "field": "排序字段(可选)", "direction": "asc|desc" } } } ``` --- ## 一、数据来源(data_source) ### 1.1 主模型(main_model) **说明**:指定统计数据的主要来源模型。 **可选值**: - `user` - 用户模型 - `company` - 公司模型 - `course_sign` - 报名模型 - `course` - 课程模型 - `course_type` - 课程分类模型 **示例**: ```json { "main_model": "user" } ``` ### 1.2 关联模型(relations) **说明**:指定需要关联的其他模型,可以关联多个模型。 **可选值**(数组): - `user` - 用户模型 - `company` - 公司模型 - `course_sign` - 报名模型 - `course` - 课程模型 - `course_type` - 课程分类模型 **注意**: - 关联模型不能包含主模型本身 - 可以关联多个模型 - 数组可以为空 **示例**: ```json { "relations": ["company", "course_sign"] } ``` --- ## 二、条件设置(conditions) ### 2.1 逻辑关系(logic) **说明**:指定多个条件之间的逻辑关系。 **可选值**: - `and` - 所有条件都必须满足(AND) - `or` - 至少一个条件满足(OR) **示例**: ```json { "logic": "and" } ``` ### 2.2 条件项(items) **说明**:条件数组,每个条件包含键名、操作类型和值。 **条件项结构**: ```json { "key": "字段名", "operator": "操作类型", "value": "值" } ``` #### 字段说明 - **key**(字符串):要查询的字段名 - 可以是主模型的字段 - 可以是关联模型的字段(使用点号分隔,如 `company.name`) - **operator**(字符串):操作类型 - `eq` - 等于 - `neq` - 不等于 - `gt` - 大于 - `egt` - 大于等于 - `lt` - 小于 - `elt` - 小于等于 - `like` - 模糊匹配 - `notlike` - 不匹配 - `in` - 在范围内(值为逗号分隔的字符串) - `notin` - 不在范围内 - `between` - 在范围内(值为逗号分隔的两个值) - `notbetween` - 不在范围内 - `isnull` - 为空(value 可省略) - `isnotnull` - 不为空(value 可省略) - **value**(字符串/数字/数组):条件值 - 根据操作类型不同,值的形式也不同 - `in` 操作:值为逗号分隔的字符串,如 `"1,2,3"` - `between` 操作:值为逗号分隔的两个值,如 `"2024-01-01,2024-12-31"` - `isnull` 和 `isnotnull` 操作:value 可以省略 **示例**: ```json { "logic": "and", "items": [ { "key": "is_schoolmate", "operator": "eq", "value": "1" }, { "key": "company.is_yh_invested", "operator": "eq", "value": "1" }, { "key": "created_at", "operator": "between", "value": "2024-01-01,2024-12-31" } ] } ``` --- ## 三、统计方式(statistics) ### 3.1 统计类型(type) **说明**:指定统计的方式。 **可选值**: - `sum` - 求和(需要指定 `field` 字段) - `max` - 最大值(需要指定 `field` 字段) - `min` - 最小值(需要指定 `field` 字段) - `count` - 统计总数量(不需要指定 `field` 字段) - `count_distinct` - 统计去重数量(需要指定 `distinct_field` 字段) **示例**: ```json { "type": "count" } ``` ### 3.2 统计字段(field) **说明**:当统计类型为 `sum`、`max` 或 `min` 时,指定要统计的字段名。 **注意**: - `type` 为 `sum`、`max`、`min` 时必须指定 `field` - `type` 为 `count` 时可以省略 `field` - 可以是主模型的字段 - 可以是关联模型的字段(使用点号分隔,如 `company.company_fund`) **示例**: ```json { "type": "sum", "field": "company_fund" } ``` ```json { "type": "max", "field": "company.company_fund" } ``` ```json { "type": "min", "field": "created_at" } ``` ### 3.3 去重字段(distinct_field) **说明**:当统计类型为 `count_distinct` 时,指定要去重的字段名。 **注意**: - `type` 为 `count_distinct` 时必须指定 `distinct_field` - 可以是主模型的字段 - 可以是关联模型的字段(使用点号分隔,如 `user.mobile`) - **可以与 `group_by` 同时使用**:可以按某个字段分组,然后统计每个分组的去重数量 **示例1:不分组去重统计** ```json { "type": "count_distinct", "distinct_field": "mobile" } ``` **示例2:关联模型字段去重** ```json { "type": "count_distinct", "distinct_field": "user.mobile" } ``` **示例3:分组 + 去重统计(组合使用)** ```json { "type": "count_distinct", "distinct_field": "user.mobile", "group_by": "course.type" } ``` ### 3.4 分组字段(group_by) **说明**:指定按哪个字段进行分组统计。这是一个可选配置,可以选择不分组或选择具体的分组字段。 **配置选项**: - **不分组**:不设置 `group_by` 字段,或设置为 `null`,将返回所有符合条件的记录列表 - **按字段分组**:设置具体的分组字段,将按该字段进行分组统计 **分组字段格式**: - 可以是主模型的字段(如:`company_area`) - 可以是关联模型的字段(使用点号分隔,如 `company.company_area`) **示例1:不分组统计** ```json { "statistics": { "type": "count" // 不设置 group_by,表示不分组 } } ``` **示例2:按主模型字段分组** ```json { "statistics": { "type": "count", "group_by": "company_area" } } ``` **示例3:按关联模型字段分组** ```json { "statistics": { "type": "count", "group_by": "company.company_area" } } ``` **示例4:分组 + 去重统计(组合使用)** ```json { "statistics": { "type": "count_distinct", "distinct_field": "user.mobile", "group_by": "course.type" } } ``` ### 3.4 排序方式(order_by) **说明**:指定结果的排序方式。 **结构**: ```json { "field": "排序字段", "direction": "asc|desc" } ``` **字段说明**: - **field**(字符串):排序字段名 - 可以是主模型的字段 - 可以是关联模型的字段(使用点号分隔) - 可以是统计结果字段(如 `total`、`count`) - **direction**(字符串):排序方向 - `asc` - 升序 - `desc` - 降序 **示例**: ```json { "order_by": { "field": "total", "direction": "desc" } } ``` --- ## 完整示例 ### 示例1:统计各区域的校友人数 ```json { "data_source": { "main_model": "user", "relations": ["company"] }, "conditions": { "logic": "and", "items": [ { "key": "is_schoolmate", "operator": "eq", "value": "1" }, { "key": "created_at", "operator": "between", "value": "2024-01-01,2024-12-31" } ] }, "statistics": { "type": "count", "group_by": "company.company_area", "order_by": { "field": "count", "direction": "desc" } } } ``` ### 示例2:统计各课程类型的报名人数 ```json { "data_source": { "main_model": "course_sign", "relations": ["course", "user"] }, "conditions": { "logic": "and", "items": [ { "key": "status", "operator": "eq", "value": "1" }, { "key": "created_at", "operator": "between", "value": "2024-01-01,2024-12-31" } ] }, "statistics": { "type": "count", "group_by": "course.type", "order_by": { "field": "count", "direction": "desc" } } } ``` ### 示例3:统计各公司的融资总额 ```json { "data_source": { "main_model": "company", "relations": ["user"] }, "conditions": { "logic": "and", "items": [ { "key": "is_yh_invested", "operator": "eq", "value": "1" }, { "key": "company_fund", "operator": "isnotnull" } ] }, "statistics": { "type": "sum", "field": "company_fund", "group_by": "company_area", "order_by": { "field": "total", "direction": "desc" } } } ``` ### 示例4:统计审核通过或待审核的报名人数 ```json { "data_source": { "main_model": "course_sign", "relations": [] }, "conditions": { "logic": "or", "items": [ { "key": "status", "operator": "eq", "value": "0" }, { "key": "status", "operator": "eq", "value": "1" } ] }, "statistics": { "type": "count", "order_by": { "field": "created_at", "direction": "desc" } } } ``` ### 示例5:统计各课程类型的去重培养人数(按手机号去重) ```json { "data_source": { "main_model": "course_sign", "relations": ["user", "course"] }, "conditions": { "logic": "and", "items": [ { "key": "status", "operator": "eq", "value": "1" }, { "key": "created_at", "operator": "between", "value": "2020-01-01," . date('Y-m-d') } ] }, "statistics": { "type": "count_distinct", "distinct_field": "user.mobile", "group_by": "course.type", "order_by": { "field": "total", "direction": "desc" } } } ``` --- ## 注意事项 1. **字段引用**: - 主模型字段直接使用字段名 - 关联模型字段使用 `模型名.字段名` 格式 - 例如:`company.name`、`course.type` 2. **数据类型**: - 所有值在 JSON 中都存储为字符串 - 系统会根据字段类型自动转换 3. **条件逻辑**: - `and` 表示所有条件都必须满足 - `or` 表示至少一个条件满足 - 条件数组可以为空(表示无条件) 4. **统计字段**: - `sum` 类型必须指定 `field` - `count` 类型不需要 `field` - 分组字段可以为空(表示不分组) 5. **排序字段**: - 可以按任意字段排序 - 可以按统计结果字段排序(如 `total`、`count`) - 排序字段可以为空(使用默认排序) --- ## 文档版本 - **创建日期**:2025-11-19 - **最后更新**:2025-11-19