You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flutter/Dart中解析店铺营业时间JSON并映射到指定模型

解析并转换店铺营业时间JSON至Dart模型类

原始输入JSON结构

原始数据是包含重复工作日记录的营业时间列表,结构如下:

"workinghours": [
    {
      "shop": 31,
      "weekday": "monday",
      "start_time": "05:25 AM",
      "end_time": "11:00 AM",
      "is_closed": false
    },
    {
      "shop": 31,
      "weekday": "monday",
      "start_time": "01:10 PM",
      "end_time": "05:00 PM",
      "is_closed": false
    }
    // 其余数据省略
  ]

目标输出JSON结构

需要转换为按「店铺+工作日」分组的层级结构:

{
  "work_time": [
    {
        "shop_id": 31,
        "week_day": "monday",
        "work_time": [
          {
            "id": 1,
            "startTime": "05:25 AM",
            "endTime": "11:00 AM",
            "isClosed": false
          },
          {
            "id": 2,
            "startTime": "01:10 PM",
            "endTime": "05:00 PM",
            "isClosed": false
          }
        ]
    }
    // 其余结构省略
  ]
}

完整Dart模型类

补全用户提供的模型类缺失的子结构,确保完全匹配目标JSON:

import 'dart:convert';

ShopWorkTimeModel shopWorkTimeModelFromJson(String str) => ShopWorkTimeModel.fromJson(json.decode(str));

String shopWorkTimeModelToJson(ShopWorkTimeModel data) => json.encode(data.toJson());

class ShopWorkTimeModel {
    ShopWorkTimeModel({
        this.workTime,
    });

    List<ShopWorkTimeModelWorkTime>? workTime;

    factory ShopWorkTimeModel.fromJson(Map<String, dynamic> json) => ShopWorkTimeModel(
        workTime: json["work_time"] == null ? [] : List<ShopWorkTimeModelWorkTime>.from(json["work_time"]!.map((x) => ShopWorkTimeModelWorkTime.fromJson(x))),
    );

    Map<String, dynamic> toJson() => {
        "work_time": workTime == null ? [] : List<dynamic>.from(workTime!.map((x) => x.toJson())),
    };
}

class ShopWorkTimeModelWorkTime {
    ShopWorkTimeModelWorkTime({
        this.shopId,
        this.weekDay,
        this.workTime,
    });

    int? shopId;
    String? weekDay;
    List<WorkTimeItem>? workTime;

    factory ShopWorkTimeModelWorkTime.fromJson(Map<String, dynamic> json) => ShopWorkTimeModelWorkTime(
        shopId: json["shop_id"],
        weekDay: json["week_day"],
        workTime: json["work_time"] == null ? [] : List<WorkTimeItem>.from(json["work_time"]!.map((x) => WorkTimeItem.fromJson(x))),
    );

    Map<String, dynamic> toJson() => {
        "shop_id": shopId,
        "week_day": weekDay,
        "work_time": workTime == null ? [] : List<dynamic>.from(workTime!.map((x) => x.toJson())),
    };
}

class WorkTimeItem {
    WorkTimeItem({
        this.id,
        this.startTime,
        this.endTime,
        this.isClosed,
    });

    int? id;
    String? startTime;
    String? endTime;
    bool? isClosed;

    factory WorkTimeItem.fromJson(Map<String, dynamic> json) => WorkTimeItem(
        id: json["id"],
        startTime: json["startTime"],
        endTime: json["endTime"],
        isClosed: json["isClosed"],
    );

    Map<String, dynamic> toJson() => {
        "id": id,
        "startTime": startTime,
        "endTime": endTime,
        "isClosed": isClosed,
    };
}

转换实现步骤与代码

1. 定义临时实体类接收原始数据

先定义临时类匹配原始JSON的字段结构,方便初始解析:

// 临时类:匹配原始输入的字段
class RawWorkingHour {
  final int shop;
  final String weekday;
  final String start_time;
  final String end_time;
  final bool is_closed;

  RawWorkingHour({
    required this.shop,
    required this.weekday,
    required this.start_time,
    required this.end_time,
    required this.is_closed,
  });

  factory RawWorkingHour.fromJson(Map<String, dynamic> json) {
    return RawWorkingHour(
      shop: json['shop'],
      weekday: json['weekday'],
      start_time: json['start_time'],
      end_time: json['end_time'],
      is_closed: json['is_closed'],
    );
  }
}

2. 核心分组与转换逻辑

通过「店铺ID+工作日」作为分组键,将同组的时间段合并,再映射到目标模型:

// 示例原始JSON字符串
String rawJson = '''
{
  "workinghours": [
    {
      "shop": 31,
      "weekday": "monday",
      "start_time": "05:25 AM",
      "end_time": "11:00 AM",
      "is_closed": false
    },
    {
      "shop": 31,
      "weekday": "monday",
      "start_time": "01:10 PM",
      "end_time": "05:00 PM",
      "is_closed": false
    },
    {
      "shop": 31,
      "weekday": "tuesday",
      "start_time": "09:00 AM",
      "end_time": "06:00 PM",
      "is_closed": false
    }
  ]
}
''';

// 转换函数:原始JSON → 目标模型
ShopWorkTimeModel convertRawToTargetModel(String rawJson) {
  // 1. 解析原始数据到临时列表
  Map<String, dynamic> rawMap = jsonDecode(rawJson);
  List<RawWorkingHour> rawHours = (rawMap['workinghours'] as List)
      .map((item) => RawWorkingHour.fromJson(item))
      .toList();

  // 2. 按「shop_weekday」分组
  Map<String, List<RawWorkingHour>> grouped = {};
  for (var hour in rawHours) {
    String key = "${hour.shop}_${hour.weekday}";
    grouped.putIfAbsent(key, () => []).add(hour);
  }

  // 3. 映射到目标模型
  List<ShopWorkTimeModelWorkTime> workTimeList = [];
  int itemIdCounter = 1; // 生成WorkTimeItem的自增ID

  grouped.forEach((key, value) {
    List<String> parts = key.split('_');
    int shopId = int.parse(parts[0]);
    String weekDay = parts[1];

    List<WorkTimeItem> timeItems = value.map((raw) {
      return WorkTimeItem(
        id: itemIdCounter++,
        startTime: raw.start_time,
        endTime: raw.end_time,
        isClosed: raw.is_closed,
      );
    }).toList();

    workTimeList.add(ShopWorkTimeModelWorkTime(
      shopId: shopId,
      weekDay: weekDay,
      workTime: timeItems,
    ));
  });

  return ShopWorkTimeModel(workTime: workTimeList);
}

3. 使用示例

void main() {
  ShopWorkTimeModel targetModel = convertRawToTargetModel(rawJson);
  // 转换为目标格式的JSON字符串
  String targetJson = shopWorkTimeModelToJson(targetModel);
  print(targetJson);
}

运行后输出的JSON将完全符合目标层级结构,且可直接通过提供的Dart模型类序列化/反序列化。

内容的提问来源于stack exchange,提问作者abdul

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 01:20:34