{
  "openapi": "3.0.3",
  "info": {
    "title": "VWCG-1346 菜品问卷评价增量接口",
    "version": "1.2.0",
    "description": "匿名H5菜品评价、Pad环境配置与PC问卷汇总的7个增量接口。"
  },
  "servers": [
    { "url": "/", "description": "当前智慧餐厅环境" }
  ],
  "tags": [
    { "name": "餐厅管理/就餐评价/问卷评价" }
  ],
  "paths": {
    "/api/dishQuestionnaire/restaurants": {
      "post": {
        "summary": "获取Pad配置可选餐厅",
        "description": "匿名只读接口，仅返回当前部署环境中启用且未删除餐厅的ID和名称，最多200项。",
        "tags": ["餐厅管理/就餐评价/问卷评价"],
        "x-apifox-folder": "餐厅管理/就餐评价/问卷评价",
        "responses": {
          "200": {
            "description": "可供Pad首次配置选择的餐厅列表",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RestaurantsResponse" } } }
          }
        }
      }
    },
    "/api/dishQuestionnaire/context": {
      "post": {
        "summary": "获取H5当前餐次评价上下文",
        "tags": ["餐厅管理/就餐评价/问卷评价"],
        "x-apifox-folder": "餐厅管理/就餐评价/问卷评价",
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": ["type"],
                "properties": {
                  "type": { "type": "integer", "minimum": 1, "description": "餐厅ID，用于区分不同餐厅的当餐菜品", "example": 1 },
                  "dishes_uuid": { "type": "string", "format": "uuid", "description": "可选的初始选中菜品UUID", "example": "25C23C4E-4C9A-56BB-67CF-F9D834EDCAAD" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "业务成功或业务失败均使用统一JSON包络",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ContextResponse" } } }
          }
        }
      }
    },
    "/api/dishQuestionnaire/submit": {
      "post": {
        "summary": "匿名提交单菜问卷评价",
        "tags": ["餐厅管理/就餐评价/问卷评价"],
        "x-apifox-folder": "餐厅管理/就餐评价/问卷评价",
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": { "$ref": "#/components/schemas/SubmitRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "首次提交或幂等重试结果",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SubmitResponse" } } }
          }
        }
      }
    },
    "/api/dishQuestionnaire/batchSubmit": {
      "post": {
        "summary": "一次提交多道菜的匿名评价",
        "description": "共享Pad会话的整批事务提交；1至20道菜，任意一项失败则整批回滚。每道菜只要求1至5分满意度，标签、具体意见和最想吃菜品均可为空。",
        "tags": ["餐厅管理/就餐评价/问卷评价"],
        "x-apifox-folder": "餐厅管理/就餐评价/问卷评价",
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": ["type", "items"],
                "properties": {
                  "type": { "type": "integer", "minimum": 1, "description": "必须与页面上下文的餐厅ID一致", "example": 1 },
                  "items": {
                    "type": "string",
                    "description": "SubmitRequest数组的JSON字符串，每道菜拥有独立submit_id；评分必填，其余评价内容选填",
                    "example": "[{\"submit_id\":\"550e8400-e29b-41d4-a716-446655440000\",\"restaurant_id\":1,\"dishes_uuid\":\"25C23C4E-4C9A-56BB-67CF-F9D834EDCAAD\",\"score\":4,\"tag_codes\":[3],\"comment\":\"口味稍咸\",\"wish_dish_name\":\"\"}]"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "整批提交结果",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BatchSubmitResponse" } } }
          }
        }
      }
    },
    "/p/DishQuestionnaire/options": {
      "post": {
        "summary": "获取PC问卷评价筛选项",
        "description": "需要PC登录、就餐评价菜单权限和餐厅数据权限。",
        "tags": ["餐厅管理/就餐评价/问卷评价"],
        "x-apifox-folder": "餐厅管理/就餐评价/问卷评价",
        "responses": {
          "200": {
            "description": "餐厅、餐次和固定口味标签",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OptionsResponse" } } }
          }
        }
      }
    },
    "/p/DishQuestionnaire/list": {
      "post": {
        "summary": "分页查询PC问卷评价聚合列表",
        "description": "数据库分页；满意率按评分大于等于4计算。",
        "tags": ["餐厅管理/就餐评价/问卷评价"],
        "x-apifox-folder": "餐厅管理/就餐评价/问卷评价",
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": { "$ref": "#/components/schemas/ListRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "按菜品、评价日期、餐次聚合的分页结果，每行包含最后评价时间",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ListResponse" } } }
          }
        }
      }
    },
    "/p/DishQuestionnaire/detail": {
      "post": {
        "summary": "分页查询菜品原始评价明细",
        "description": "需要重新校验餐厅数据范围，不能仅凭菜品UUID越权读取。",
        "tags": ["餐厅管理/就餐评价/问卷评价"],
        "x-apifox-folder": "餐厅管理/就餐评价/问卷评价",
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "allOf": [
                  { "$ref": "#/components/schemas/ListRequest" },
                  {
                    "type": "object",
                    "required": ["dishes_uuid"],
                    "properties": { "dishes_uuid": { "type": "string", "format": "uuid" } }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "原始评价明细分页结果",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DetailResponse" } } }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "SubmitRequest": {
        "type": "object",
        "required": ["type", "submit_id", "restaurant_id", "dishes_uuid", "score"],
        "properties": {
          "type": { "type": "integer", "minimum": 1, "description": "餐厅ID，必须与restaurant_id一致", "example": 1 },
          "submit_id": { "type": "string", "minLength": 16, "maxLength": 64, "example": "550e8400-e29b-41d4-a716-446655440000" },
          "restaurant_id": { "type": "integer", "minimum": 1, "example": 1 },
          "dishes_uuid": { "type": "string", "format": "uuid" },
          "score": { "type": "integer", "minimum": 1, "maximum": 5 },
          "tag_codes": { "type": "array", "uniqueItems": true, "items": { "type": "integer", "minimum": 1, "maximum": 8 }, "example": [3, 5] },
          "comment": { "type": "string", "maxLength": 500, "example": "口味可以再淡一点" },
          "wish_dish_name": { "type": "string", "maxLength": 30, "example": "水煮鱼" }
        }
      },
      "ListRequest": {
        "type": "object",
        "properties": {
          "restaurant_id": { "type": "integer", "minimum": 1 },
          "date_start": { "type": "string", "format": "date" },
          "date_end": { "type": "string", "format": "date" },
          "meal_times": { "type": "integer", "minimum": 1, "maximum": 4 },
          "tag_code": { "type": "integer", "minimum": 1, "maximum": 8 },
          "keyword": { "type": "string", "maxLength": 64 },
          "page": { "type": "integer", "minimum": 1, "default": 1 },
          "page_size": { "type": "integer", "minimum": 1, "maximum": 100, "default": 15 }
        }
      },
      "ContextResponse": {
        "type": "object",
        "properties": {
          "code": { "type": "integer", "example": 0 },
          "message": { "type": "string", "example": "查询成功" },
          "data": {
            "type": "object",
            "properties": {
              "type": { "type": "integer", "description": "当前餐厅ID" },
              "restaurant": { "type": "object", "properties": { "id": { "type": "integer" }, "name": { "type": "string" } } },
              "meal_date": { "type": "string", "format": "date" },
              "meal_times": { "type": "integer" },
              "meal_times_name": { "type": "string" },
              "server_time": { "type": "string" },
              "dishes": { "type": "array", "items": { "$ref": "#/components/schemas/Dish" } },
              "selected_dish": { "nullable": true, "allOf": [{ "$ref": "#/components/schemas/Dish" }] },
              "tags": { "type": "array", "items": { "$ref": "#/components/schemas/Tag" } }
            }
          }
        }
      },
      "RestaurantsResponse": {
        "type": "object",
        "properties": {
          "code": { "type": "integer", "example": 0 },
          "message": { "type": "string", "example": "查询成功" },
          "data": {
            "type": "array",
            "maxItems": 200,
            "items": {
              "type": "object",
              "required": ["id", "name"],
              "properties": {
                "id": { "type": "integer", "minimum": 1, "example": 1 },
                "name": { "type": "string", "example": "一楼智慧餐厅" }
              }
            }
          }
        }
      },
      "SubmitResponse": {
        "type": "object",
        "properties": {
          "code": { "type": "integer", "example": 0 },
          "message": { "type": "string", "example": "评价提交成功" },
          "data": { "type": "object", "properties": { "id": { "type": "integer" }, "uuid": { "type": "string" }, "submit_id": { "type": "string" }, "duplicated": { "type": "boolean" } } }
        }
      },
      "BatchSubmitResponse": {
        "type": "object",
        "properties": {
          "code": { "type": "integer", "example": 0 },
          "message": { "type": "string", "example": "评价提交成功" },
          "data": {
            "type": "object",
            "properties": {
              "submitted_count": { "type": "integer", "example": 2 },
              "results": { "type": "array", "items": { "$ref": "#/components/schemas/SubmitResult" } }
            }
          }
        }
      },
      "SubmitResult": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "uuid": { "type": "string" },
          "submit_id": { "type": "string" },
          "duplicated": { "type": "boolean" }
        }
      },
      "OptionsResponse": { "type": "object", "properties": { "code": { "type": "integer" }, "message": { "type": "string" }, "data": { "type": "object", "properties": { "restaurants": { "type": "array", "items": { "$ref": "#/components/schemas/Option" } }, "meal_times": { "type": "array", "items": { "$ref": "#/components/schemas/Option" } }, "tags": { "type": "array", "items": { "$ref": "#/components/schemas/Option" } } } } } },
      "ListResponse": { "type": "object", "properties": { "code": { "type": "integer" }, "message": { "type": "string" }, "data": { "type": "object", "properties": { "rows": { "type": "array", "items": { "$ref": "#/components/schemas/QuestionnaireListRow" } }, "total": { "type": "integer" }, "page": { "type": "integer" }, "page_size": { "type": "integer" } } } } },
      "QuestionnaireListRow": { "type": "object", "properties": { "dishes_uuid": { "type": "string", "format": "uuid" }, "dishes_name": { "type": "string" }, "meal_date": { "type": "string", "format": "date" }, "meal_times": { "type": "integer", "minimum": 1, "maximum": 4 }, "evaluation_count": { "type": "integer" }, "average_score": { "type": "number" }, "satisfaction_rate": { "type": "number" }, "suggestion_count": { "type": "integer" }, "last_evaluation_time": { "type": "string" }, "tag_counts": { "type": "array", "items": { "type": "object", "properties": { "code": { "type": "integer" }, "name": { "type": "string" }, "count": { "type": "integer" } } } }, "wish_counts": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string" }, "count": { "type": "integer" } } } } } },
      "DetailResponse": { "type": "object", "properties": { "code": { "type": "integer" }, "message": { "type": "string" }, "data": { "$ref": "#/components/schemas/Page" } } },
      "Page": { "type": "object", "properties": { "rows": { "type": "array", "items": { "type": "object" } }, "total": { "type": "integer" }, "page": { "type": "integer" }, "page_size": { "type": "integer" } } },
      "Dish": { "type": "object", "properties": { "uuid": { "type": "string", "format": "uuid" }, "name": { "type": "string" }, "file_path": { "type": "string" } } },
      "Tag": { "type": "object", "properties": { "code": { "type": "integer" }, "name": { "type": "string" } } },
      "Option": { "type": "object", "properties": { "value": { "oneOf": [{ "type": "integer" }, { "type": "string" }] }, "label": { "type": "string" } } }
    }
  }
}
