diff --git a/app/Models/Course.php b/app/Models/Course.php index 938673b..8a764e5 100755 --- a/app/Models/Course.php +++ b/app/Models/Course.php @@ -6,7 +6,6 @@ namespace App\Models; use EasyWeChat\Factory; use Illuminate\Filesystem\Filesystem; -use App\Models\Config; class Course extends SoftDeletesModel { @@ -300,20 +299,12 @@ class Course extends SoftDeletesModel /** * 获取课程统计项元数据 * 返回每个统计项的计算逻辑和验证方法说明 - * 从 configs 表中读取,key = 'statistics_metadata' + * 从 statistics_metadata 表中读取 * @return array */ public static function getStatisticsMetadata() { - $value = Config::getValueByKey('statistics_metadata'); - if ($value) { - $data = json_decode($value, true); - if (json_last_error() === JSON_ERROR_NONE && is_array($data)) { - return $data; - } - } - // 如果数据库中没有数据或解析失败,返回空数组 - return []; + return StatisticsMetadata::getAllAsArray(); } } diff --git a/app/Models/StatisticsMetadata.php b/app/Models/StatisticsMetadata.php new file mode 100644 index 0000000..ba138f3 --- /dev/null +++ b/app/Models/StatisticsMetadata.php @@ -0,0 +1,36 @@ +first(); + } + + /** + * 获取所有统计元数据,以 key 为索引的数组 + * @return array + */ + public static function getAllAsArray() + { + $items = self::all(); + $result = []; + foreach ($items as $item) { + $result[$item->key] = [ + 'name' => $item->name, + 'from' => $item->from, + 'verify' => $item->verify, + ]; + } + return $result; + } +} diff --git a/database/migrations/2026_01_16_111947_create_statistics_metadata_table.php b/database/migrations/2026_01_16_111947_create_statistics_metadata_table.php new file mode 100644 index 0000000..a3840eb --- /dev/null +++ b/database/migrations/2026_01_16_111947_create_statistics_metadata_table.php @@ -0,0 +1,38 @@ +comment('统计指标元数据'); + $table->increments('id'); + $table->string('key')->unique()->comment('统计项标识,如 course_signs_total'); + $table->string('name')->comment('统计项名称'); + $table->text('from')->nullable()->comment('统计逻辑说明'); + $table->text('verify')->nullable()->comment('验证方法说明'); + $table->text('remark')->nullable()->comment('备注'); + $table->dateTime('created_at')->nullable(); + $table->dateTime('updated_at')->nullable(); + $table->dateTime('deleted_at')->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('statistics_metadata'); + } +}; diff --git a/database/seeders/StatisticsMetadataSeeder.php b/database/seeders/StatisticsMetadataSeeder.php new file mode 100644 index 0000000..642321d --- /dev/null +++ b/database/seeders/StatisticsMetadataSeeder.php @@ -0,0 +1,56 @@ +command->warn('统计指标说明.json 文件不存在,跳过数据填充'); + return; + } + + $jsonContent = File::get($jsonPath); + $data = json_decode($jsonContent, true); + + if (json_last_error() !== JSON_ERROR_NONE) { + $this->command->error('JSON 文件解析失败:' . json_last_error_msg()); + return; + } + + if (!is_array($data)) { + $this->command->error('JSON 数据格式不正确,应为对象/数组'); + return; + } + + // 清空现有数据(可选,根据需要决定是否保留) + // StatisticsMetadata::truncate(); + + // 插入数据 + foreach ($data as $key => $item) { + StatisticsMetadata::updateOrCreate( + ['key' => $key], + [ + 'name' => $item['name'] ?? '', + 'from' => $item['from'] ?? '', + 'verify' => $item['verify'] ?? '', + ] + ); + } + + $this->command->info('统计指标元数据填充完成,共处理 ' . count($data) . ' 条记录'); + } +} diff --git a/统计指标说明.json b/统计指标说明.json index cc3dc4b..f460385 100644 --- a/统计指标说明.json +++ b/统计指标说明.json @@ -1,17 +1,17 @@ { "course_signs_total": { "name": "报名人数", - "from": "1、统计指定时间范围和课程范围内的所有报名记录数量,包括所有状态的报名(待审核、已通过、已拒绝等);2、加上历史课程数据中的人数统计;3、注意:一个学员报名多个课程会计算多次。", + "from": "1、统计指定时间范围和课程范围内的所有报名记录数量,包括所有状态的报名(待审核、已通过、已拒绝等);2、加上额外添加的课程数据中的人数统计;3、注意:一个学员报名多个课程会计算多次。", "verify": "" }, "course_signs_pass": { "name": "培养人次(未去重)", - "from": "1、统计指定课程体系下的指定时间范围内的课程(课程开始或结束时间在时间范围内)下审核通过的报名记录数量;2、统计历史课程(关联的分类是历史课程,关联的日历是统计人数选项)里满足时间范围内的课程(课程开始或结束时间在时间范围内)培养人数未去重的数据;3、将两部分数据相加得到总数。", + "from": "1、统计指定课程体系下的指定时间范围内的课程(课程开始或结束时间在时间范围内)下审核通过的报名记录数量;2、统计额外添加的课程数据(关联的分类是历史课程,关联的日历是统计人数选项)里满足时间范围内的课程(课程开始或结束时间在时间范围内)培养人数未去重的数据;3、将两部分数据相加得到总数。", "verify": "报名管理栏目,累加统计对比" }, "course_signs_pass_unique": { "name": "培养人数(已去重)", - "from": "1、统计指定课程体系下的指定时间范围内的课程(课程开始或结束时间在时间范围内)下审核通过的报名记录数量按照手机号去重;2、统计历史课程(关联的分类是历史课程,关联的日历是统计人数选项)里满足时间范围内的课程(课程开始或结束时间在时间范围内)培养人数去重的数据;3、将两部分数据相加得到总数。", + "from": "1、统计指定课程体系下的指定时间范围内的课程(课程开始或结束时间在时间范围内)下审核通过的报名记录数量按照手机号去重;2、统计额外添加的课程数据(关联的分类是历史课程,关联的日历是统计人数选项)里满足时间范围内的课程(课程开始或结束时间在时间范围内)培养人数去重的数据;3、将两部分数据相加得到总数。", "verify": "" }, "course_total": {