fix: 修复 VoiceController Map.of 兼容性 + ExploreController 参数不匹配

- VoiceController: Map.of() -> Collections.singletonMap() 兼容 Java 8
- ExploreController: 补齐 takeoutService.roll() 缺失的 taste/priceRange/allergies 参数

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
王鹏
2026-05-08 20:02:27 +08:00
commit 802b4ba229
98 changed files with 5761 additions and 0 deletions

69
backend/pom.xml Normal file
View File

@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.18</version>
</parent>
<groupId>com.chowbox</groupId>
<artifactId>chowbox-backend</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.5</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,13 @@
package com.chowbox;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.chowbox.mapper")
public class ChowBoxApplication {
public static void main(String[] args) {
SpringApplication.run(ChowBoxApplication.class, args);
}
}

View File

@@ -0,0 +1,17 @@
package com.chowbox.config;
import com.chowbox.model.ApiResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ApiResponse<?> handleException(Exception e) {
log.error("Unhandled exception: {}", e.getMessage(), e);
return ApiResponse.fail(500, "服务器出了点小差,请稍后再试");
}
}

View File

@@ -0,0 +1,21 @@
package com.chowbox.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
return template;
}
}

View File

@@ -0,0 +1,16 @@
package com.chowbox.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "OPTIONS")
.allowedHeaders("*");
}
}

View File

@@ -0,0 +1,31 @@
package com.chowbox.controller;
import com.chowbox.model.ApiResponse;
import com.chowbox.model.Restaurant;
import com.chowbox.service.TakeoutService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
@RestController
@RequestMapping("/api/explore")
public class ExploreController {
@Autowired
private TakeoutService takeoutService;
@PostMapping("/roll")
public ApiResponse<Restaurant> roll(@RequestBody Map<String, Object> body) {
double lat = Double.parseDouble(String.valueOf(body.get("latitude")));
double lng = Double.parseDouble(String.valueOf(body.get("longitude")));
String openid = (String) body.getOrDefault("openid", "anonymous");
// Phase 2: 差异化过滤条件(堂食场景)。Phase 1 复用外卖逻辑
Restaurant result = takeoutService.roll(lat, lng, openid, "都可以", "all", "");
if (result == null) {
return ApiResponse.fail(404, "附近暂无推荐好店,换片区域试试?");
}
return ApiResponse.ok(result);
}
}

View File

@@ -0,0 +1,52 @@
package com.chowbox.controller;
import com.chowbox.model.ApiResponse;
import com.chowbox.model.FridgeMatchResult;
import com.chowbox.service.FridgeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Slf4j
@RestController
@RequestMapping("/api/fridge")
public class FridgeController {
@Autowired
private FridgeService fridgeService;
@PostMapping("/match")
public ApiResponse<List<FridgeMatchResult>> match(@RequestBody Map<String, Object> body) {
Object ingObj = body.get("ingredients");
log.info("Fridge match request: ingredients type={}, value={}", ingObj != null ? ingObj.getClass().getSimpleName() : "null", ingObj);
List<String> ingredients = new ArrayList<>();
if (ingObj instanceof List) {
for (Object item : (List<?>) ingObj) {
if (item != null) ingredients.add(item.toString());
}
}
if (ingredients.isEmpty()) {
return ApiResponse.fail(400, "请输入至少一种食材");
}
// 接收前端自定义常备调料
List<String> staples = new ArrayList<>();
Object stapleObj = body.get("staples");
if (stapleObj instanceof List) {
for (Object item : (List<?>) stapleObj) {
if (item != null) staples.add(item.toString());
}
}
log.info("Fridge match: parsed ingredients={}, staples={}", ingredients, staples);
List<FridgeMatchResult> results = fridgeService.matchRecipes(ingredients, staples);
log.info("Fridge match: {} results", results.size());
return ApiResponse.ok(results);
}
}

View File

@@ -0,0 +1,24 @@
package com.chowbox.controller;
import com.chowbox.model.ApiResponse;
import com.chowbox.model.Recipe;
import com.chowbox.service.FridgeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/recipe")
public class RecipeController {
@Autowired
private FridgeService fridgeService;
@GetMapping("/{id}")
public ApiResponse<Recipe> detail(@PathVariable Long id) {
Recipe recipe = fridgeService.getRecipeDetail(id);
if (recipe == null) {
return ApiResponse.fail(404, "菜谱不存在");
}
return ApiResponse.ok(recipe);
}
}

View File

@@ -0,0 +1,33 @@
package com.chowbox.controller;
import com.chowbox.model.ApiResponse;
import com.chowbox.model.Restaurant;
import com.chowbox.service.TakeoutService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
@RestController
@RequestMapping("/api/takeout")
public class TakeoutController {
@Autowired
private TakeoutService takeoutService;
@PostMapping("/roll")
public ApiResponse<Restaurant> roll(@RequestBody Map<String, Object> body) {
double lat = Double.parseDouble(String.valueOf(body.get("latitude")));
double lng = Double.parseDouble(String.valueOf(body.get("longitude")));
String openid = (String) body.getOrDefault("openid", "anonymous");
String taste = (String) body.getOrDefault("taste", "都可以");
String priceRange = (String) body.getOrDefault("priceRange", "all");
String allergies = (String) body.getOrDefault("allergies", "");
Restaurant result = takeoutService.roll(lat, lng, openid, taste, priceRange, allergies);
if (result == null) {
return ApiResponse.fail(404, "附近暂无合适的商家,换个区域试试吧");
}
return ApiResponse.ok(result);
}
}

View File

@@ -0,0 +1,29 @@
package com.chowbox.controller;
import com.chowbox.model.ApiResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.Collections;
import java.util.Map;
/**
* 语音识别接口STT stub
* 当前返回空文本,后续可接入阿里云/腾讯云 ASR 服务。
*/
@Slf4j
@RestController
@RequestMapping("/api/voice")
public class VoiceController {
@PostMapping("/recognize")
public ApiResponse<Map<String, String>> recognize(@RequestParam("audio") MultipartFile audio) {
log.info("Voice recognize: file={}, size={}bytes", audio.getOriginalFilename(), audio.getSize());
// TODO: 接入 ASR 服务,对音频做语音识别
// 目前 stub 返回空结果,前端会 fallback 提示用户手动输入
return ApiResponse.ok(Collections.singletonMap("text", ""));
}
}

View File

@@ -0,0 +1,9 @@
package com.chowbox.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.chowbox.model.RecipeIngredient;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface RecipeIngredientMapper extends BaseMapper<RecipeIngredient> {
}

View File

@@ -0,0 +1,9 @@
package com.chowbox.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.chowbox.model.Recipe;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface RecipeMapper extends BaseMapper<Recipe> {
}

View File

@@ -0,0 +1,9 @@
package com.chowbox.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.chowbox.model.RecipeStep;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface RecipeStepMapper extends BaseMapper<RecipeStep> {
}

View File

@@ -0,0 +1,25 @@
package com.chowbox.model;
import lombok.Data;
@Data
public class ApiResponse<T> {
private int code;
private String message;
private T data;
public static <T> ApiResponse<T> ok(T data) {
ApiResponse<T> r = new ApiResponse<>();
r.code = 200;
r.message = "success";
r.data = data;
return r;
}
public static <T> ApiResponse<T> fail(int code, String message) {
ApiResponse<T> r = new ApiResponse<>();
r.code = code;
r.message = message;
return r;
}
}

View File

@@ -0,0 +1,11 @@
package com.chowbox.model;
import lombok.Data;
import java.util.List;
@Data
public class FridgeMatchResult {
private Recipe recipe;
private double matchRate; // 匹配度 0-100
private List<String> missingIngredients; // 缺少的食材
}

View File

@@ -0,0 +1,25 @@
package com.chowbox.model;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.util.List;
@Data
@TableName("recipes")
public class Recipe {
private Long id;
private String name;
private Integer difficulty;
private Integer cookTime;
private String imageUrl;
private String category;
private String season;
private String mealTime;
@TableField(exist = false)
private List<RecipeIngredient> ingredients;
@TableField(exist = false)
private List<RecipeStep> steps;
}

View File

@@ -0,0 +1,14 @@
package com.chowbox.model;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("recipe_ingredients")
public class RecipeIngredient {
private Long id;
private Long recipeId;
private String ingredientName;
private String amount;
private Integer isStaple;
}

View File

@@ -0,0 +1,14 @@
package com.chowbox.model;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("recipe_steps")
public class RecipeStep {
private Long id;
private Long recipeId;
private Integer stepOrder;
private String content;
private String imageUrl;
}

View File

@@ -0,0 +1,24 @@
package com.chowbox.model;
import lombok.Data;
@Data
public class Restaurant {
private String id;
private String name;
private String address;
private Double rating;
private Integer monthlySales;
private Double avgPrice;
private Double distance;
private Double longitude;
private Double latitude;
private String deliveryTime;
private String deliveryFee;
private String minOrder;
private String phone;
private String imageUrl;
private String category;
private String recommendReason;
private String[] signatureDishes;
}

View File

@@ -0,0 +1,197 @@
package com.chowbox.service;
import com.chowbox.model.Restaurant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@Slf4j
@Service
public class AmapService {
private static final String AMAP_AROUND_URL = "https://restapi.amap.com/v3/place/around";
@Value("${amap.api-key}")
private String apiKey;
@Autowired
private RedisTemplate<String, Object> redisTemplate;
private final RestTemplate restTemplate = new RestTemplate();
@SuppressWarnings("unchecked")
public List<Restaurant> searchNearbyPOI(double lat, double lng, int radius) {
String gridKey = String.format("poi:%.3f:%.3f:restaurant",
Math.floor(lat * 10) / 10, Math.floor(lng * 10) / 10);
List<Restaurant> cached = (List<Restaurant>) redisTemplate.opsForValue().get(gridKey);
if (cached != null && !cached.isEmpty()) {
log.info("Amap cache hit: key={}, size={}", gridKey, cached.size());
return cached;
}
String url = String.format(
"%s?key=%s&location=%f,%f&radius=%d&types=050000&offset=50&extensions=all",
AMAP_AROUND_URL, apiKey, lng, lat, radius);
log.info("Amap API call: location={},{} radius={}", lat, lng, radius);
try {
Map<String, Object> response = restTemplate.getForObject(url, Map.class);
List<Restaurant> results = parseResponse(response, lat, lng);
log.info("Amap parsed: {} restaurants", results.size());
if (!results.isEmpty()) {
redisTemplate.opsForValue().set(gridKey, results, 1, TimeUnit.HOURS);
}
return results;
} catch (Exception e) {
log.error("Amap API error: {}", e.getMessage(), e);
return Collections.emptyList();
}
}
@SuppressWarnings("unchecked")
private List<Restaurant> parseResponse(Map<String, Object> response, double centerLat, double centerLng) {
if (response == null) {
log.warn("Amap response is null");
return Collections.emptyList();
}
String status = String.valueOf(response.get("status"));
if (!"1".equals(status)) {
log.warn("Amap response status={}, info={}", status, response.get("info"));
return Collections.emptyList();
}
Object poisObj = response.get("pois");
if (poisObj == null) {
log.warn("Amap response has no 'pois' key");
return Collections.emptyList();
}
List<Map<String, Object>> pois = (List<Map<String, Object>>) poisObj;
log.info("Amap POIs count: {}", pois.size());
return pois.stream().map(poi -> parseRestaurant(poi, centerLat, centerLng))
.collect(Collectors.toList());
}
@SuppressWarnings("unchecked")
private Restaurant parseRestaurant(Map<String, Object> poi, double centerLat, double centerLng) {
Restaurant r = new Restaurant();
r.setId(String.valueOf(poi.get("id")));
r.setName(String.valueOf(poi.get("name")));
r.setAddress(String.valueOf(poi.get("address")));
// 坐标 - 用于后续地图导航
try {
String[] locParts = String.valueOf(poi.get("location")).split(",");
if (locParts.length == 2) {
r.setLongitude(Double.parseDouble(locParts[0]));
r.setLatitude(Double.parseDouble(locParts[1]));
}
} catch (Exception ignored) {
r.setLongitude(centerLng);
r.setLatitude(centerLat);
}
// 距离
Object distObj = poi.get("distance");
if (distObj instanceof String) r.setDistance(Double.parseDouble((String) distObj));
else if (distObj instanceof Number) r.setDistance(((Number) distObj).doubleValue());
// biz_ext: 评分、人均
Object bizExtObj = poi.get("biz_ext");
if (bizExtObj instanceof Map) {
Map<String, Object> bizExt = (Map<String, Object>) bizExtObj;
try { r.setRating(Double.parseDouble(String.valueOf(bizExt.get("rating")))); } catch (Exception ignored) {}
try { r.setAvgPrice(Double.parseDouble(String.valueOf(bizExt.get("cost")))); } catch (Exception ignored) {}
}
// 分类
r.setCategory(detectCategory(poi));
// 标签 → 用作招牌菜来源
Object tagObj = poi.get("tag");
if (tagObj instanceof String && !((String) tagObj).isEmpty()) {
r.setSignatureDishes(extractTags((String) tagObj));
} else if (tagObj instanceof List && !((List<?>) tagObj).isEmpty()) {
List<String> tags = ((List<?>) tagObj).stream()
.map(String::valueOf).collect(Collectors.toList());
r.setSignatureDishes(tags.toArray(new String[0]));
}
// 电话
Object telObj = poi.get("tel");
if (telObj instanceof String) r.setPhone((String) telObj);
else if (telObj instanceof List) {
r.setPhone(String.join(";", ((List<?>) telObj).stream()
.map(String::valueOf).collect(Collectors.toList())));
}
// 照片
Object photosObj = poi.get("photos");
if (photosObj instanceof List) {
List<?> photos = (List<?>) photosObj;
if (!photos.isEmpty()) {
Object firstPhoto = photos.get(0);
if (firstPhoto instanceof Map) {
Map<String, Object> photoMap = (Map<String, Object>) firstPhoto;
Object url = photoMap.get("url");
if (url != null) {
r.setImageUrl(url.toString());
if (url.toString().startsWith("http://")) {
r.setImageUrl(url.toString().replace("http://", "https://"));
}
}
}
}
}
return r;
}
/**
* 从 type 和 tag 字段推断可读的分类名
*/
private String detectCategory(Map<String, Object> poi) {
// type 格式如 "050100|中餐厅|050100"
String type = String.valueOf(poi.getOrDefault("type", ""));
if (type.contains("川菜")) return "川菜";
if (type.contains("粤菜")) return "粤菜";
if (type.contains("湘菜")) return "湘菜";
if (type.contains("火锅")) return "火锅";
if (type.contains("烧烤")) return "烧烤";
if (type.contains("日料") || type.contains("日本")) return "日料";
if (type.contains("韩餐") || type.contains("韩国")) return "韩餐";
if (type.contains("西餐") || type.contains("西式")) return "西餐";
if (type.contains("快餐")) return "快餐";
if (type.contains("小吃")) return "小吃";
if (type.contains("咖啡")) return "咖啡";
if (type.contains("甜品")) return "甜品";
if (type.contains("") || type.contains("")) return "面馆";
String tag = String.valueOf(poi.getOrDefault("tag", ""));
if (!tag.isEmpty() && !"null".equals(tag)) {
return tag;
}
return "餐饮";
}
/**
* 从标签字符串中提取关键词作为招牌菜
*/
private String[] extractTags(String tagStr) {
if (tagStr == null || tagStr.isEmpty()) return null;
return Arrays.stream(tagStr.split("[;,\\s]+"))
.map(String::trim)
.filter(t -> !t.isEmpty())
.limit(4)
.toArray(String[]::new);
}
}

View File

@@ -0,0 +1,183 @@
package com.chowbox.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.chowbox.mapper.RecipeIngredientMapper;
import com.chowbox.mapper.RecipeMapper;
import com.chowbox.mapper.RecipeStepMapper;
import com.chowbox.model.FridgeMatchResult;
import com.chowbox.model.Recipe;
import com.chowbox.model.RecipeIngredient;
import com.chowbox.model.RecipeStep;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j
@Service
public class FridgeService {
@Autowired
private RecipeMapper recipeMapper;
@Autowired
private RecipeIngredientMapper ingredientMapper;
@Autowired
private RecipeStepMapper stepMapper;
private static final Set<String> DEFAULT_STAPLES = new HashSet<>(Arrays.asList(
"", "", "酱油", "生抽", "老抽", "", "料酒", "蚝油",
"", "白糖", "淀粉", "香油", "", "", "", "干辣椒", "花椒"
));
private static final Random RANDOM = new Random();
public List<FridgeMatchResult> matchRecipes(List<String> userIngredients, List<String> customStaples) {
Set<String> userSet = new HashSet<>();
for (String ing : userIngredients) {
userSet.add(ing.trim());
}
// 合并系统默认 + 用户自定义常备调料
Set<String> allStaples = new HashSet<>(DEFAULT_STAPLES);
if (customStaples != null) {
for (String s : customStaples) {
allStaples.add(s.trim());
}
}
userSet.addAll(allStaples);
List<Recipe> allRecipes = recipeMapper.selectList(null);
log.info("FridgeService: total recipes in DB = {}", allRecipes.size());
List<FridgeMatchResult> results = new ArrayList<>();
int currentHour = LocalTime.now().getHour();
int currentMonth = LocalDate.now().getMonthValue();
String mealTime = getMealTime(currentHour);
String season = getSeason(currentMonth);
log.info("FridgeService: current mealTime={}, season={}", mealTime, season);
for (Recipe recipe : allRecipes) {
List<RecipeIngredient> recipeIngredients = ingredientMapper.selectList(
new QueryWrapper<RecipeIngredient>().eq("recipe_id", recipe.getId())
);
List<String> recipeIngNames = recipeIngredients.stream()
.map(ri -> ri.getIngredientName().trim())
.collect(Collectors.toList());
// 计算交集
long matchCount = recipeIngNames.stream()
.filter(userSet::contains)
.count();
double matchRate = recipeIngNames.isEmpty() ? 0 :
(double) matchCount / recipeIngNames.size() * 100;
// 找出缺失的食材(非调料类)
List<String> missing = recipeIngNames.stream()
.filter(name -> !userSet.contains(name) && !allStaples.contains(name))
.collect(Collectors.toList());
// 时段/季节加权:匹配当前时段或季节 +8%
double timeBoost = 0;
if (mealTime.equals(recipe.getMealTime())) timeBoost += 8;
if (season.equals(recipe.getSeason())) timeBoost += 8;
FridgeMatchResult result = new FridgeMatchResult();
result.setRecipe(recipe);
result.setMatchRate(Math.round(matchRate + timeBoost));
result.setMissingIngredients(missing);
results.add(result);
}
// 按匹配度降序排列,取 Top10 候选池,加权随机选 3-5 个
List<FridgeMatchResult> pool = results.stream()
.sorted((a, b) -> Double.compare(b.getMatchRate(), a.getMatchRate()))
.limit(10)
.collect(Collectors.toList());
return weightedRandomPick(pool);
}
/**
* 从候选池加权随机选 3-5 个。
* 权重 = matchRate²保证高分菜更有机会但不乏惊喜。
*/
private List<FridgeMatchResult> weightedRandomPick(List<FridgeMatchResult> pool) {
if (pool.size() <= 3) return pool;
int pickCount = 3 + RANDOM.nextInt(Math.min(3, pool.size() - 2)); // 3-5
List<FridgeMatchResult> shuffled = new ArrayList<>(pool);
Collections.shuffle(shuffled, RANDOM);
// 加权随机
List<FridgeMatchResult> picked = new ArrayList<>();
List<FridgeMatchResult> remaining = new ArrayList<>(shuffled);
for (int i = 0; i < pickCount && !remaining.isEmpty(); i++) {
double totalWeight = remaining.stream()
.mapToDouble(r -> Math.pow(r.getMatchRate(), 2))
.sum();
if (totalWeight <= 0) {
int idx = RANDOM.nextInt(remaining.size());
picked.add(remaining.remove(idx));
continue;
}
double dart = RANDOM.nextDouble() * totalWeight;
double cumulative = 0;
int selectedIdx = 0;
for (int j = 0; j < remaining.size(); j++) {
cumulative += Math.pow(remaining.get(j).getMatchRate(), 2);
if (dart <= cumulative) {
selectedIdx = j;
break;
}
}
picked.add(remaining.remove(selectedIdx));
}
// 匹配度高的排前面
picked.sort((a, b) -> Double.compare(b.getMatchRate(), a.getMatchRate()));
return picked;
}
private String getMealTime(int hour) {
if (hour >= 5 && hour < 10) return "早餐";
if (hour >= 10 && hour < 14) return "午餐";
if (hour >= 14 && hour < 17) return "下午茶";
if (hour >= 17 && hour < 21) return "晚餐";
return "夜宵";
}
private String getSeason(int month) {
if (month >= 3 && month <= 5) return "春季";
if (month >= 6 && month <= 8) return "夏季";
if (month >= 9 && month <= 11) return "秋季";
return "冬季";
}
public Recipe getRecipeDetail(Long recipeId) {
Recipe recipe = recipeMapper.selectById(recipeId);
if (recipe == null) return null;
List<RecipeIngredient> ingredients = ingredientMapper.selectList(
new QueryWrapper<RecipeIngredient>().eq("recipe_id", recipeId)
);
List<RecipeStep> steps = stepMapper.selectList(
new QueryWrapper<RecipeStep>().eq("recipe_id", recipeId).orderByAsc("step_order")
);
recipe.setIngredients(ingredients);
recipe.setSteps(steps);
return recipe;
}
}

View File

@@ -0,0 +1,320 @@
package com.chowbox.service;
import com.chowbox.model.Restaurant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j
@Service
public class TakeoutService {
@Autowired
private AmapService amapService;
private final Map<String, Set<String>> recentlyShown = new HashMap<>();
// 保质期较短的缓存,避免同一会话内重复展示
private static final int MAX_SHOWN_HISTORY = 20;
public Restaurant roll(double lat, double lng, String openid,
String taste, String priceRange, String allergies) {
List<Restaurant> all = amapService.searchNearbyPOI(lat, lng, 3000);
log.info("Takeout roll: total POIs={}", all.size());
if (!all.isEmpty()) {
Restaurant first = all.get(0);
log.info("Takeout sample: name={}, rating={}, category={}, tags={}",
first.getName(), first.getRating(), first.getCategory(),
first.getSignatureDishes() != null ? String.join(",", first.getSignatureDishes()) : "null");
}
if (all.isEmpty()) return null;
// ── 高质量池过滤(分层降级) ──
List<Restaurant> pool = filterByRating(all, 4.3);
if (pool.size() < 3) {
log.info("Takeout pool >=4.3: {}, expanding to >=4.0", pool.size());
pool = filterByRating(all, 4.0);
}
if (pool.size() < 3) {
log.info("Takeout pool >=4.0: {}, expanding to >=3.5", pool.size());
pool = filterByRating(all, 3.5);
}
if (pool.isEmpty()) {
log.info("Takeout fallback: using all POIs");
pool = new ArrayList<>(all);
}
// ── 去除最近已展示的商家 ──
Set<String> shown = recentlyShown.getOrDefault(openid, new LinkedHashSet<>());
List<Restaurant> candidates = pool.stream()
.filter(r -> !shown.contains(r.getId()))
.collect(Collectors.toList());
if (candidates.isEmpty()) {
// 全部展示过了,清空历史重来
recentlyShown.remove(openid);
candidates = new ArrayList<>(pool);
}
// ── 用户偏好过滤 ──
List<Restaurant> prefFiltered = filterByPreferences(candidates, taste, priceRange, allergies);
if (!prefFiltered.isEmpty()) {
candidates = prefFiltered;
} else {
log.info("Takeout pref filter empty, fallback to all candidates");
}
// ── 加权随机(评分权重 + 距离惩罚) ──
Restaurant selected = weightedRandom(candidates);
// 记录已展示
Set<String> userShown = recentlyShown.computeIfAbsent(openid,
k -> new LinkedHashSet<>());
userShown.add(selected.getId());
// 限制历史大小
if (userShown.size() > MAX_SHOWN_HISTORY) {
Iterator<String> it = userShown.iterator();
it.next();
it.remove();
}
// ── 补充合理默认值 ──
enrichRestaurant(selected);
return selected;
}
private List<Restaurant> filterByRating(List<Restaurant> list, double minRating) {
return list.stream()
.filter(r -> r.getRating() != null && r.getRating() >= minRating)
.collect(Collectors.toList());
}
/**
* 根据用户偏好过滤餐厅列表,三层过滤:价格 → 口味 → 忌口
*/
private List<Restaurant> filterByPreferences(List<Restaurant> list,
String taste, String priceRange, String allergies) {
List<Restaurant> result = new ArrayList<>(list);
// 1. 价格区间过滤
if (priceRange != null && !"all".equals(priceRange)) {
result = filterByPriceRange(result, priceRange);
}
// 2. 口味偏好过滤
if (taste != null && !"都可以".equals(taste)) {
result = filterByTaste(result, taste);
}
// 3. 忌口过滤
if (allergies != null && !allergies.isEmpty()) {
result = filterByAllergies(result, allergies);
}
return result;
}
private List<Restaurant> filterByPriceRange(List<Restaurant> list, String priceRange) {
return list.stream().filter(r -> {
Double price = r.getAvgPrice();
if (price == null) return true; // 无价格数据的保留
switch (priceRange) {
case "low": return price < 30;
case "medium": return price >= 30 && price <= 80;
case "high": return price > 80;
default: return true;
}
}).collect(Collectors.toList());
}
private List<Restaurant> filterByTaste(List<Restaurant> list, String taste) {
return list.stream().filter(r -> {
String cat = r.getCategory() != null ? r.getCategory() : "";
String name = r.getName() != null ? r.getName() : "";
switch (taste) {
case "":
return containsAny(cat, "川菜", "湘菜", "火锅", "烧烤", "麻辣", "香锅")
|| name.contains("火锅") || name.contains("烧烤") || name.contains("麻辣");
case "清淡":
return containsAny(cat, "粤菜", "日料", "面馆", "粥粉面", "蒸菜", "轻食")
|| name.contains("") || name.contains("") || name.contains("");
case "酸甜":
return containsAny(cat, "甜品", "咖啡", "饮品", "东南亚", "糖水")
|| name.contains("甜品") || name.contains("咖啡") || name.contains("");
default:
return true;
}
}).collect(Collectors.toList());
}
private List<Restaurant> filterByAllergies(List<Restaurant> list, String allergies) {
String[] items = allergies.split("[,]");
return list.stream().filter(r -> {
String cat = r.getCategory() != null ? r.getCategory() : "";
String name = r.getName() != null ? r.getName() : "";
String[] dishes = r.getSignatureDishes() != null ? r.getSignatureDishes() : new String[0];
String combined = cat + name + String.join("", dishes);
for (String item : items) {
String kw = item.trim();
if (!kw.isEmpty() && combined.contains(kw)) {
return false;
}
}
return true;
}).collect(Collectors.toList());
}
private boolean containsAny(String text, String... keywords) {
for (String kw : keywords) {
if (text.contains(kw)) return true;
}
return false;
}
private Restaurant weightedRandom(List<Restaurant> candidates) {
// 综合权重 = 评分² × e^(-distance/2000)
double totalWeight = 0;
double[] weights = new double[candidates.size()];
for (int i = 0; i < candidates.size(); i++) {
Restaurant r = candidates.get(i);
double rating = r.getRating() != null ? r.getRating() : 3.5;
double dist = r.getDistance() != null ? r.getDistance() : 1500;
// 评分权重为主,距离越近权重越高
weights[i] = rating * rating * Math.exp(-dist / 2000.0);
totalWeight += weights[i];
}
double random = Math.random() * totalWeight;
double cumulative = 0;
for (int i = 0; i < candidates.size(); i++) {
cumulative += weights[i];
if (random <= cumulative) {
return candidates.get(i);
}
}
return candidates.get(candidates.size() - 1);
}
/**
* 用合理数据填充缺失字段,不再硬编码假数据
*/
private void enrichRestaurant(Restaurant r) {
Double rating = r.getRating();
Double avgPrice = r.getAvgPrice();
Double distance = r.getDistance();
// ── 推荐语:基于真实数据生成 ──
if (r.getRecommendReason() == null || r.getRecommendReason().isEmpty()) {
r.setRecommendReason(buildRecommendReason(rating, avgPrice, r.getCategory()));
}
// ── 招牌菜:如果 POI 没有 tag 数据 → 从菜系推断 ──
if (r.getSignatureDishes() == null || r.getSignatureDishes().length == 0) {
r.setSignatureDishes(guessSignatureDishes(r.getCategory(), r.getName()));
}
// ── 配送/起送信息:基于品类和人均估算 ──
if (r.getDeliveryTime() == null) {
r.setDeliveryTime(estimateDeliveryTime(distance));
}
if (r.getMinOrder() == null) {
r.setMinOrder(estimateMinOrder(avgPrice, r.getCategory()));
}
if (r.getDeliveryFee() == null) {
r.setDeliveryFee(estimateDeliveryFee(distance));
}
}
private String buildRecommendReason(Double rating, Double avgPrice, String category) {
List<String> points = new ArrayList<>();
if (rating != null && rating >= 4.5) {
points.add("评分" + rating + ",口碑极佳");
} else if (rating != null && rating >= 4.0) {
points.add("评分" + rating + ",广受好评");
} else if (rating != null) {
points.add("评分" + rating);
}
if (avgPrice != null && avgPrice <= 30) {
points.add("人均¥" + avgPrice.intValue() + ",超高性价比");
} else if (avgPrice != null && avgPrice <= 60) {
points.add("人均¥" + avgPrice.intValue());
}
if (category != null && !"餐饮".equals(category)) {
points.add("热门" + category);
}
if (points.isEmpty()) {
points.add("附近人气商家");
}
return String.join(" · ", points);
}
private String[] guessSignatureDishes(String category, String name) {
if (category == null) category = "";
if (name == null) name = "";
List<String> guesses = new ArrayList<>();
// 从店名提取线索
if (name.contains("火锅")) guesses.add("鸳鸯锅底");
if (name.contains("烧烤")) guesses.add("羊肉串");
if (name.contains("") || category.equals("面馆")) guesses.add("招牌汤面");
if (name.contains("饺子") || name.contains("水饺")) guesses.add("手工水饺");
if (name.contains("米线") || name.contains("米粉")) guesses.add("过桥米线");
if (name.contains("汉堡") || name.contains("炸鸡")) guesses.add("招牌汉堡");
// 从菜系推断
if (category.contains("川菜")) { guesses.add("水煮鱼"); guesses.add("麻婆豆腐"); }
if (category.contains("粤菜")) { guesses.add("白切鸡"); guesses.add("叉烧"); }
if (category.contains("湘菜")) { guesses.add("剁椒鱼头"); guesses.add("小炒肉"); }
if (category.contains("日料")) { guesses.add("三文鱼刺身"); guesses.add("豚骨拉面"); }
if (category.contains("韩餐")) { guesses.add("石锅拌饭"); guesses.add("韩式炸鸡"); }
if (category.contains("火锅")) { guesses.add("毛肚"); guesses.add("虾滑"); }
if (category.contains("烧烤")) { guesses.add("烤串套餐"); guesses.add("烤茄子"); }
if (category.contains("快餐")) { guesses.add("超值套餐"); }
if (category.contains("甜品") || category.contains("咖啡")) { guesses.add("招牌拿铁"); guesses.add("提拉米苏"); }
// 不够3个用通用项补齐
if (guesses.size() < 3) guesses.add("招牌套餐");
return guesses.subList(0, Math.min(guesses.size(), 4)).toArray(new String[0]);
}
private String estimateDeliveryTime(Double distanceMeters) {
if (distanceMeters == null) return "约30分钟";
double km = distanceMeters / 1000.0;
if (km <= 1) return "约25分钟";
if (km <= 2) return "约30分钟";
if (km <= 3) return "约35分钟";
return "约40分钟";
}
private String estimateMinOrder(Double avgPrice, String category) {
// 快餐/小吃类起送低,正餐类高
if (category != null && (category.contains("快餐") || category.contains("小吃"))) {
return "15元起送";
}
if (avgPrice != null && avgPrice >= 80) {
return "30元起送";
}
return "20元起送";
}
private String estimateDeliveryFee(Double distanceMeters) {
if (distanceMeters == null) return "约3元";
double km = distanceMeters / 1000.0;
if (km <= 1.5) return "免配送费";
if (km <= 2.5) return "约3元";
return "约5元";
}
}

View File

@@ -0,0 +1,24 @@
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://localhost:3306/chowbox?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
redis:
host: localhost
port: 6379
password:
timeout: 3000ms
mybatis-plus:
configuration:
map-underscore-to-camel-case: true
global-config:
db-config:
id-type: auto
amap:
api-key: e35f0d06a77ab57ba1e6806120b46c2a

View File

@@ -0,0 +1,382 @@
-- ChowBox 菜谱种子数据100道
USE chowbox;
-- ============================================================
-- 家常快手菜20道- 难度低、时间短
-- ============================================================
INSERT INTO recipes (id, name, difficulty, cook_time, category, season, meal_time) VALUES
(1, '西红柿炒鸡蛋', 1, 10, '家常菜', 'all', 'all'),
(2, '酸辣土豆丝', 1, 10, '家常菜', 'all', 'lunch,dinner'),
(3, '青椒肉丝', 1, 15, '家常菜', 'all', 'lunch,dinner'),
(4, '蒜蓉西兰花', 1, 8, '家常菜', 'all', 'lunch,dinner'),
(5, '糖醋里脊', 2, 25, '家常菜', 'all', 'lunch,dinner'),
(6, '干煸四季豆', 1, 12, '家常菜', 'all', 'lunch,dinner'),
(7, '可乐鸡翅', 1, 20, '家常菜', 'all', 'lunch,dinner'),
(8, '韭黄炒蛋', 1, 8, '家常菜', 'all', 'all'),
(9, '红烧豆腐', 1, 15, '家常菜', 'all', 'lunch,dinner'),
(10, '蚝油生菜', 1, 5, '家常菜', 'all', 'lunch,dinner'),
(11, '孜然土豆片', 1, 12, '家常菜', 'all', 'lunch,dinner'),
(12, '洋葱炒肉', 1, 10, '家常菜', 'all', 'lunch,dinner'),
(13, '香菇油菜', 1, 10, '家常菜', 'all', 'lunch,dinner'),
(14, '家常豆腐', 2, 18, '家常菜', 'all', 'lunch,dinner'),
(15, '雪菜肉丝', 1, 12, '家常菜', 'all', 'lunch,dinner'),
(16, '素炒豆芽', 1, 6, '家常菜', 'all', 'lunch,dinner'),
(17, '芹菜香干', 1, 10, '家常菜', 'all', 'lunch,dinner'),
(18, '番茄菜花', 1, 10, '家常菜', 'all', 'lunch,dinner'),
(19, '肉末茄子', 2, 20, '家常菜', 'all', 'lunch,dinner'),
(20, '葱爆羊肉', 2, 15, '家常菜', 'winter', 'lunch,dinner');
-- ============================================================
-- 川菜15道
-- ============================================================
INSERT INTO recipes (id, name, difficulty, cook_time, category, season, meal_time) VALUES
(21, '麻婆豆腐', 2, 15, '川菜', 'all', 'lunch,dinner'),
(22, '回锅肉', 2, 25, '川菜', 'all', 'lunch,dinner'),
(23, '宫保鸡丁', 2, 20, '川菜', 'all', 'lunch,dinner'),
(24, '水煮肉片', 3, 30, '川菜', 'winter', 'lunch,dinner'),
(25, '鱼香肉丝', 2, 20, '川菜', 'all', 'lunch,dinner'),
(26, '辣子鸡丁', 3, 30, '川菜', 'all', 'lunch,dinner'),
(27, '夫妻肺片', 2, 20, '川菜', 'summer', 'lunch,dinner'),
(28, '口水鸡', 2, 30, '川菜', 'summer', 'lunch,dinner'),
(29, '干煸牛肉丝', 2, 20, '川菜', 'all', 'lunch,dinner'),
(30, '蒜泥白肉', 1, 20, '川菜', 'summer', 'lunch,dinner'),
(31, '酸菜鱼', 3, 35, '川菜', 'winter', 'lunch,dinner'),
(32, '毛血旺', 3, 30, '川菜', 'winter', 'lunch,dinner'),
(33, '麻辣香锅', 2, 25, '川菜', 'all', 'lunch,dinner'),
(34, '泡椒凤爪', 2, 40, '川菜', 'summer', 'all'),
(35, '担担面', 2, 25, '川菜', 'all', 'lunch,dinner');
-- ============================================================
-- 粤菜15道
-- ============================================================
INSERT INTO recipes (id, name, difficulty, cook_time, category, season, meal_time) VALUES
(36, '白切鸡', 3, 40, '粤菜', 'all', 'lunch,dinner'),
(37, '清蒸鲈鱼', 2, 20, '粤菜', 'all', 'lunch,dinner'),
(38, '白灼虾', 1, 10, '粤菜', 'all', 'lunch,dinner'),
(39, '广式叉烧', 4, 60, '粤菜', 'all', 'lunch,dinner'),
(40, '菠萝咕咾肉', 2, 25, '粤菜', 'summer', 'lunch,dinner'),
(41, '干炒牛河', 3, 15, '粤菜', 'all', 'lunch,dinner'),
(42, '蒜蓉粉丝蒸扇贝', 2, 15, '粤菜', 'all', 'dinner'),
(43, '豉汁蒸排骨', 2, 25, '粤菜', 'all', 'lunch,dinner'),
(44, '煲仔饭', 3, 35, '粤菜', 'winter', 'lunch,dinner'),
(45, '冬瓜排骨汤', 1, 50, '粤菜', 'summer', 'dinner'),
(46, '蚝油牛肉', 2, 15, '粤菜', 'all', 'lunch,dinner'),
(47, '虾饺', 4, 40, '粤菜', 'all', 'breakfast,lunch'),
(48, '肠粉', 2, 20, '粤菜', 'all', 'breakfast'),
(49, '叉烧包', 3, 45, '粤菜', 'all', 'breakfast'),
(50, '蛋挞', 2, 30, '粤菜', 'all', 'all');
-- ============================================================
-- 湘菜8道
-- ============================================================
INSERT INTO recipes (id, name, difficulty, cook_time, category, season, meal_time) VALUES
(51, '剁椒鱼头', 3, 30, '湘菜', 'winter', 'lunch,dinner'),
(52, '农家小炒肉', 2, 15, '湘菜', 'all', 'lunch,dinner'),
(53, '酸豆角肉末', 1, 12, '湘菜', 'summer', 'lunch,dinner'),
(54, '腊味合蒸', 2, 30, '湘菜', 'winter', 'lunch,dinner'),
(55, '干锅花菜', 2, 18, '湘菜', 'all', 'lunch,dinner'),
(56, '口味虾', 3, 35, '湘菜', 'summer', 'dinner'),
(57, '擂辣椒皮蛋', 1, 10, '湘菜', 'summer', 'all'),
(58, '湘西外婆菜', 2, 15, '湘菜', 'all', 'lunch,dinner');
-- ============================================================
-- 东北菜8道
-- ============================================================
INSERT INTO recipes (id, name, difficulty, cook_time, category, season, meal_time) VALUES
(59, '锅包肉', 3, 30, '东北菜', 'all', 'lunch,dinner'),
(60, '地三鲜', 2, 20, '东北菜', 'all', 'lunch,dinner'),
(61, '猪肉炖粉条', 2, 40, '东北菜', 'winter', 'lunch,dinner'),
(62, '东北乱炖', 1, 35, '东北菜', 'winter', 'lunch,dinner'),
(63, '京酱肉丝', 2, 20, '东北菜', 'all', 'lunch,dinner'),
(64, '拔丝地瓜', 3, 25, '东北菜', 'winter', 'dinner'),
(65, '酸菜白肉', 2, 45, '东北菜', 'winter', 'lunch,dinner'),
(66, '溜肉段', 2, 20, '东北菜', 'all', 'lunch,dinner');
-- ============================================================
-- 早餐类12道
-- ============================================================
INSERT INTO recipes (id, name, difficulty, cook_time, category, season, meal_time) VALUES
(67, '鸡蛋灌饼', 2, 15, '早餐', 'all', 'breakfast'),
(68, '皮蛋瘦肉粥', 1, 30, '早餐', 'all', 'breakfast'),
(69, '葱花鸡蛋饼', 1, 8, '早餐', 'all', 'breakfast'),
(70, '小米南瓜粥', 1, 25, '早餐', 'autumn,winter', 'breakfast'),
(71, '煎饺', 2, 15, '早餐', 'all', 'breakfast'),
(72, '三明治', 1, 5, '早餐', 'all', 'breakfast'),
(73, '豆浆油条', 3, 40, '早餐', 'all', 'breakfast'),
(74, '馄饨', 3, 30, '早餐', 'all', 'breakfast,lunch'),
(75, '肉夹馍', 3, 60, '早餐', 'all', 'all'),
(76, '糯米鸡', 2, 40, '早餐', 'all', 'breakfast'),
(77, '煎饼果子', 2, 15, '早餐', 'all', 'breakfast'),
(78, '豆沙包', 2, 40, '早餐', 'all', 'breakfast');
-- ============================================================
-- 汤羹类8道
-- ============================================================
INSERT INTO recipes (id, name, difficulty, cook_time, category, season, meal_time) VALUES
(79, '番茄蛋花汤', 1, 10, '汤羹', 'all', 'lunch,dinner'),
(80, '紫菜蛋花汤', 1, 5, '汤羹', 'all', 'lunch,dinner'),
(81, '玉米排骨汤', 1, 60, '汤羹', 'all', 'dinner'),
(82, '西湖牛肉羹', 2, 25, '汤羹', 'winter', 'dinner'),
(83, '酸辣汤', 2, 15, '汤羹', 'winter', 'lunch,dinner'),
(84, '鲫鱼豆腐汤', 2, 30, '汤羹', 'all', 'dinner'),
(85, '莲藕排骨汤', 1, 60, '汤羹', 'autumn,winter', 'dinner'),
(86, '银耳莲子羹', 1, 40, '汤羹', 'summer,autumn', 'all');
-- ============================================================
-- 凉菜类8道
-- ============================================================
INSERT INTO recipes (id, name, difficulty, cook_time, category, season, meal_time) VALUES
(87, '凉拌黄瓜', 1, 5, '凉菜', 'summer', 'lunch,dinner'),
(88, '皮蛋豆腐', 1, 5, '凉菜', 'summer', 'lunch,dinner'),
(89, '凉拌木耳', 1, 8, '凉菜', 'summer', 'lunch,dinner'),
(90, '凉拌三丝', 1, 10, '凉菜', 'summer', 'lunch,dinner'),
(91, '糖拌番茄', 1, 3, '凉菜', 'summer', 'all'),
(92, '凉拌鸡丝', 1, 15, '凉菜', 'summer', 'lunch,dinner'),
(93, '拍黄瓜', 1, 3, '凉菜', 'summer', 'lunch,dinner'),
(94, '凉拌海带丝', 1, 8, '凉菜', 'summer', 'lunch,dinner');
-- ============================================================
-- 主食类6道
-- ============================================================
INSERT INTO recipes (id, name, difficulty, cook_time, category, season, meal_time) VALUES
(95, '蛋炒饭', 1, 8, '主食', 'all', 'all'),
(96, '番茄鸡蛋面', 1, 12, '主食', 'all', 'all'),
(97, '炸酱面', 2, 25, '主食', 'all', 'lunch,dinner'),
(98, '葱油拌面', 1, 10, '主食', 'all', 'all'),
(99, '炒米粉', 1, 10, '主食', 'all', 'all'),
(100, '阳春面', 1, 8, '主食', 'all', 'breakfast,lunch');
-- ============================================================
-- 菜谱食材数据
-- ============================================================
-- 家常快手菜 (1-20)
INSERT INTO recipe_ingredients (recipe_id, ingredient_name, amount, is_staple) VALUES
(1, '西红柿', '2个', 1),(1, '鸡蛋', '3个', 1),(1, '', '1根', 0),(1, '', '少许', 0),(1, '', '适量', 0),
(2, '土豆', '2个', 1),(2, '干辣椒', '3个', 0),(2, '花椒', '少许', 0),(2, '', '1勺', 0),(2, '', '适量', 0),
(3, '猪肉', '150克', 1),(3, '青椒', '2个', 1),(3, '', '2片', 0),(3, '', '2瓣', 0),(3, '生抽', '1勺', 0),(3, '料酒', '1勺', 0),(3, '', '适量', 0),(3, '淀粉', '少许', 0),
(4, '西兰花', '1颗', 1),(4, '', '5瓣', 0),(4, '', '适量', 0),(4, '蚝油', '1勺', 0),
(5, '猪里脊', '200克', 1),(5, '鸡蛋', '1个', 0),(5, '淀粉', '适量', 0),(5, '番茄酱', '3勺', 0),(5, '', '2勺', 0),(5, '', '1勺', 0),(5, '', '适量', 0),
(6, '四季豆', '300克', 1),(6, '干辣椒', '5个', 0),(6, '花椒', '少许', 0),(6, '', '3瓣', 0),(6, '', '适量', 0),
(7, '鸡翅', '10个', 1),(7, '可乐', '1罐', 0),(7, '', '3片', 0),(7, '生抽', '2勺', 0),(7, '料酒', '1勺', 0),(7, '', '适量', 0),
(8, '韭黄', '200克', 1),(8, '鸡蛋', '3个', 1),(8, '', '适量', 0),
(9, '豆腐', '1块', 1),(9, '', '3瓣', 0),(9, '生抽', '2勺', 0),(9, '蚝油', '1勺', 0),(9, '', '少许', 0),(9, '', '适量', 0),
(10, '生菜', '300克', 1),(10, '', '5瓣', 0),(10, '蚝油', '2勺', 0),(10, '', '适量', 0),
(11, '土豆', '2个', 1),(11, '孜然粉', '1勺', 0),(11, '辣椒粉', '适量', 0),(11, '', '适量', 0),
(12, '洋葱', '1个', 1),(12, '猪肉', '150克', 1),(12, '生抽', '1勺', 0),(12, '料酒', '1勺', 0),(12, '', '适量', 0),
(13, '香菇', '8朵', 1),(13, '油菜', '200克', 1),(13, '', '3瓣', 0),(13, '蚝油', '1勺', 0),(13, '', '适量', 0),
(14, '豆腐', '1块', 1),(14, '青椒', '1个', 0),(14, '木耳', '适量', 0),(14, '生抽', '2勺', 0),(14, '蚝油', '1勺', 0),(14, '', '适量', 0),
(15, '雪菜', '100克', 1),(15, '猪肉', '150克', 1),(15, '', '2片', 0),(15, '料酒', '1勺', 0),(15, '', '适量', 0),
(16, '豆芽', '300克', 1),(16, '', '3瓣', 0),(16, '', '1勺', 0),(16, '干辣椒', '3个', 0),(16, '', '适量', 0),
(17, '芹菜', '200克', 1),(17, '香干', '150克', 1),(17, '', '2瓣', 0),(17, '生抽', '1勺', 0),(17, '', '适量', 0),
(18, '番茄', '2个', 1),(18, '菜花', '300克', 1),(18, '', '3瓣', 0),(18, '', '适量', 0),(18, '', '少许', 0),
(19, '茄子', '2根', 1),(19, '猪肉末', '100克', 1),(19, '', '5瓣', 0),(19, '', '2片', 0),(19, '生抽', '2勺', 0),(19, '蚝油', '1勺', 0),(19, '', '少许', 0),(19, '', '适量', 0),
(20, '羊肉', '200克', 1),(20, '大葱', '2根', 1),(20, '', '2片', 0),(20, '料酒', '1勺', 0),(20, '生抽', '1勺', 0),(20, '', '适量', 0),(20, '孜然粉', '少许', 0);
-- 川菜 (21-35)
INSERT INTO recipe_ingredients (recipe_id, ingredient_name, amount, is_staple) VALUES
(21, '豆腐', '1块', 1),(21, '猪肉末', '80克', 0),(21, '豆瓣酱', '1勺', 0),(21, '花椒粉', '少许', 0),(21, '', '2片', 0),(21, '', '3瓣', 0),(21, '生抽', '1勺', 0),
(22, '五花肉', '300克', 1),(22, '蒜苗', '3根', 1),(22, '豆瓣酱', '1勺', 0),(22, '', '2片', 0),(22, '', '3瓣', 0),(22, '生抽', '1勺', 0),(22, '料酒', '1勺', 0),
(23, '鸡胸肉', '300克', 1),(23, '花生米', '50克', 1),(23, '干辣椒', '5个', 0),(23, '花椒', '少许', 0),(23, '', '2片', 0),(23, '', '3瓣', 0),(23, '生抽', '1勺', 0),(23, '', '1勺', 0),(23, '', '1勺', 0),(23, '料酒', '1勺', 0),(23, '淀粉', '少许', 0),
(24, '猪肉', '200克', 1),(24, '白菜', '200克', 1),(24, '豆芽', '100克', 0),(24, '干辣椒', '10个', 0),(24, '花椒', '1勺', 0),(24, '豆瓣酱', '1勺', 0),(24, '', '3片', 0),(24, '', '5瓣', 0),
(25, '猪肉', '200克', 1),(25, '木耳', '适量', 0),(25, '胡萝卜', '半根', 0),(25, '青椒', '1个', 0),(25, '豆瓣酱', '1勺', 0),(25, '', '2片', 0),(25, '', '3瓣', 0),(25, '生抽', '1勺', 0),(25, '', '1勺', 0),(25, '', '1勺', 0),(25, '淀粉', '少许', 0),
(26, '鸡腿肉', '300克', 1),(26, '干辣椒', '15个', 0),(26, '花椒', '1勺', 0),(26, '', '3片', 0),(26, '', '5瓣', 0),(26, '料酒', '1勺', 0),(26, '生抽', '1勺', 0),(26, '淀粉', '少许', 0),(26, '', '适量', 0),
(27, '牛腱子', '300克', 1),(27, '牛肚', '150克', 1),(27, '花生米', '50克', 0),(27, '香菜', '适量', 0),(27, '辣椒油', '2勺', 0),(27, '花椒粉', '少许', 0),(27, '', '5瓣', 0),(27, '生抽', '2勺', 0),(27, '', '1勺', 0),(27, '', '少许', 0),
(28, '鸡腿', '2只', 1),(28, '', '5片', 0),(28, '', '2根', 0),(28, '辣椒油', '2勺', 0),(28, '花椒粉', '少许', 0),(28, '生抽', '2勺', 0),(28, '', '1勺', 0),(28, '', '少许', 0),(28, '', '5瓣', 0),(28, '花生碎', '适量', 0),
(29, '牛肉', '200克', 1),(29, '芹菜', '100克', 1),(29, '干辣椒', '5个', 0),(29, '', '2片', 0),(29, '', '3瓣', 0),(29, '生抽', '1勺', 0),(29, '料酒', '1勺', 0),(29, '', '适量', 0),
(30, '五花肉', '300克', 1),(30, '', '10瓣', 0),(30, '', '3片', 0),(30, '生抽', '2勺', 0),(30, '', '1勺', 0),(30, '辣椒油', '2勺', 0),(30, '', '少许', 0),(30, '料酒', '1勺', 0),
(31, '草鱼', '1条', 1),(31, '酸菜', '200克', 1),(31, '干辣椒', '5个', 0),(31, '花椒', '少许', 0),(31, '', '5片', 0),(31, '', '5瓣', 0),(31, '料酒', '2勺', 0),(31, '淀粉', '适量', 0),(31, '', '适量', 0),
(32, '鸭血', '200克', 1),(32, '毛肚', '150克', 1),(32, '午餐肉', '100克', 1),(32, '豆芽', '100克', 0),(32, '干辣椒', '10个', 0),(32, '花椒', '1勺', 0),(32, '豆瓣酱', '1勺', 0),(32, '', '5片', 0),(32, '', '5瓣', 0),
(33, '', '150克', 1),(33, '', '100克', 1),(33, '土豆', '1个', 1),(33, '花菜', '100克', 0),(33, '干辣椒', '10个', 0),(33, '花椒', '1勺', 0),(33, '豆瓣酱', '1勺', 0),(33, '', '5瓣', 0),(33, '', '3片', 0),(33, '生抽', '1勺', 0),
(34, '鸡爪', '500克', 1),(34, '泡椒', '10个', 0),(34, '', '5片', 0),(34, '', '5瓣', 0),(34, '料酒', '2勺', 0),(34, '白醋', '2勺', 0),(34, '', '适量', 0),
(35, '面条', '200克', 1),(35, '猪肉末', '100克', 0),(35, '芝麻酱', '2勺', 0),(35, '辣椒油', '1勺', 0),(35, '花椒粉', '少许', 0),(35, '生抽', '1勺', 0),(35, '', '少许', 0),(35, '', '3瓣', 0),(35, '', '1根', 0);
-- 粤菜 (36-50)
INSERT INTO recipe_ingredients (recipe_id, ingredient_name, amount, is_staple) VALUES
(36, '', '1只', 1),(36, '', '5片', 0),(36, '', '3根', 0),(36, '料酒', '2勺', 0),(36, '', '适量', 0),
(37, '鲈鱼', '1条', 1),(37, '', '5片', 0),(37, '', '2根', 0),(37, '蒸鱼豉油', '2勺', 0),(37, '料酒', '1勺', 0),(37, '', '适量', 0),
(38, '', '500克', 1),(38, '', '3片', 0),(38, '料酒', '1勺', 0),(38, '', '适量', 0),
(39, '梅花肉', '500克', 1),(39, '叉烧酱', '3勺', 0),(39, '蜂蜜', '2勺', 0),(39, '生抽', '2勺', 0),(39, '料酒', '1勺', 0),(39, '', '3片', 0),(39, '', '3瓣', 0),
(40, '猪里脊', '200克', 1),(40, '菠萝', '150克', 1),(40, '青椒', '1个', 0),(40, '番茄酱', '3勺', 0),(40, '', '2勺', 0),(40, '', '1勺', 0),(40, '淀粉', '适量', 0),(40, '', '适量', 0),(40, '鸡蛋', '1个', 0),
(41, '河粉', '300克', 1),(41, '牛肉', '150克', 1),(41, '豆芽', '100克', 0),(41, '', '2根', 0),(41, '生抽', '2勺', 0),(41, '老抽', '1勺', 0),(41, '料酒', '1勺', 0),(41, '淀粉', '少许', 0),
(42, '扇贝', '6个', 1),(42, '粉丝', '1把', 0),(42, '', '10瓣', 0),(42, '生抽', '1勺', 0),(42, '蚝油', '1勺', 0),(42, '', '适量', 0),
(43, '排骨', '300克', 1),(43, '豆豉', '1勺', 0),(43, '', '5瓣', 0),(43, '', '2片', 0),(43, '生抽', '1勺', 0),(43, '料酒', '1勺', 0),(43, '淀粉', '少许', 0),(43, '', '少许', 0),
(44, '大米', '200克', 1),(44, '腊肠', '1根', 1),(44, '排骨', '150克', 1),(44, '油菜', '3棵', 0),(44, '生抽', '2勺', 0),(44, '蚝油', '1勺', 0),(44, '', '2片', 0),(44, '', '适量', 0),
(45, '排骨', '300克', 1),(45, '冬瓜', '500克', 1),(45, '', '3片', 0),(45, '', '适量', 0),(45, '料酒', '1勺', 0),
(46, '牛肉', '200克', 1),(46, '青椒', '1个', 0),(46, '蚝油', '2勺', 0),(46, '', '2片', 0),(46, '', '3瓣', 0),(46, '生抽', '1勺', 0),(46, '料酒', '1勺', 0),(46, '淀粉', '少许', 0),
(47, '虾仁', '200克', 1),(47, '', '50克', 1),(47, '澄粉', '150克', 1),(47, '淀粉', '50克', 0),(47, '猪油', '少许', 0),(47, '', '适量', 0),(47, '', '少许', 0),
(48, '大米', '200克', 1),(48, '虾仁', '50克', 1),(48, '牛肉', '50克', 1),(48, '鸡蛋', '1个', 0),(48, '生抽', '1勺', 0),(48, '', '适量', 0),
(49, '面粉', '250克', 1),(49, '叉烧肉', '150克', 1),(49, '酵母', '3克', 0),(49, '', '30克', 0),(49, '蚝油', '1勺', 0),(49, '生抽', '1勺', 0),
(50, '鸡蛋', '2个', 1),(50, '牛奶', '100毫升', 1),(50, '', '30克', 0),(50, '面粉', '80克', 0),(50, '黄油', '10克', 0);
-- 湘菜 (51-58)
INSERT INTO recipe_ingredients (recipe_id, ingredient_name, amount, is_staple) VALUES
(51, '鱼头', '1个', 1),(51, '剁椒', '100克', 0),(51, '', '5片', 0),(51, '', '5瓣', 0),(51, '', '2根', 0),(51, '料酒', '2勺', 0),(51, '蒸鱼豉油', '2勺', 0),(51, '', '适量', 0),
(52, '五花肉', '200克', 1),(52, '青椒', '5个', 1),(52, '', '5瓣', 0),(52, '', '2片', 0),(52, '生抽', '1勺', 0),(52, '', '适量', 0),
(53, '酸豆角', '200克', 1),(53, '猪肉末', '150克', 1),(53, '干辣椒', '3个', 0),(53, '', '3瓣', 0),(53, '', '2片', 0),(53, '生抽', '1勺', 0),(53, '', '适量', 0),
(54, '腊肉', '200克', 1),(54, '腊鱼', '150克', 1),(54, '', '3片', 0),(54, '', '3瓣', 0),(54, '干辣椒', '3个', 0),(54, '料酒', '1勺', 0),
(55, '花菜', '300克', 1),(55, '五花肉', '80克', 0),(55, '干辣椒', '5个', 0),(55, '', '5瓣', 0),(55, '生抽', '1勺', 0),(55, '', '适量', 0),
(56, '小龙虾', '1000克', 1),(56, '干辣椒', '15个', 0),(56, '花椒', '1勺', 0),(56, '豆瓣酱', '1勺', 0),(56, '', '5片', 0),(56, '', '10瓣', 0),(56, '生抽', '2勺', 0),(56, '料酒', '2勺', 0),(56, '', '少许', 0),(56, '', '适量', 0),
(57, '青椒', '4个', 1),(57, '皮蛋', '2个', 1),(57, '', '5瓣', 0),(57, '', '1勺', 0),(57, '生抽', '1勺', 0),(57, '', '适量', 0),
(58, '猪肉末', '150克', 1),(58, '萝卜干', '50克', 1),(58, '干辣椒', '3个', 0),(58, '', '3瓣', 0),(58, '生抽', '1勺', 0),(58, '', '适量', 0);
-- 东北菜 (59-66)
INSERT INTO recipe_ingredients (recipe_id, ingredient_name, amount, is_staple) VALUES
(59, '猪里脊', '250克', 1),(59, '淀粉', '适量', 0),(59, '鸡蛋', '1个', 0),(59, '胡萝卜', '半根', 0),(59, '', '3片', 0),(59, '', '3勺', 0),(59, '白醋', '3勺', 0),(59, '', '适量', 0),
(60, '土豆', '1个', 1),(60, '茄子', '1根', 1),(60, '青椒', '1个', 1),(60, '', '5瓣', 0),(60, '生抽', '2勺', 0),(60, '', '少许', 0),(60, '', '适量', 0),(60, '淀粉', '少许', 0),
(61, '五花肉', '200克', 1),(61, '粉条', '100克', 1),(61, '白菜', '200克', 0),(61, '', '3片', 0),(61, '', '3瓣', 0),(61, '生抽', '2勺', 0),(61, '老抽', '1勺', 0),(61, '料酒', '1勺', 0),(61, '', '适量', 0),
(62, '排骨', '200克', 1),(62, '土豆', '1个', 1),(62, '豆角', '200克', 1),(62, '玉米', '1根', 0),(62, '', '3片', 0),(62, '生抽', '2勺', 0),(62, '', '适量', 0),
(63, '猪里脊', '200克', 1),(63, '大葱', '2根', 1),(63, '豆腐皮', '适量', 0),(63, '', '2片', 0),(63, '甜面酱', '2勺', 0),(63, '', '少许', 0),(63, '生抽', '1勺', 0),(63, '淀粉', '少许', 0),
(64, '地瓜', '1个', 1),(64, '', '150克', 0),(64, '', '适量', 0),
(65, '五花肉', '300克', 1),(65, '酸菜', '200克', 1),(65, '', '3片', 0),(65, '', '3瓣', 0),(65, '料酒', '1勺', 0),(65, '', '适量', 0),
(66, '猪里脊', '200克', 1),(66, '青椒', '1个', 0),(66, '胡萝卜', '半根', 0),(66, '淀粉', '适量', 0),(66, '', '2片', 0),(66, '', '3瓣', 0),(66, '生抽', '2勺', 0),(66, '', '1勺', 0),(66, '', '1勺', 0),(66, '', '适量', 0);
-- 早餐类 (67-78)
INSERT INTO recipe_ingredients (recipe_id, ingredient_name, amount, is_staple) VALUES
(67, '面粉', '200克', 1),(67, '鸡蛋', '2个', 1),(67, '', '2根', 0),(67, '', '适量', 0),
(68, '大米', '100克', 1),(68, '皮蛋', '2个', 1),(68, '猪肉末', '50克', 0),(68, '', '2片', 0),(68, '', '适量', 0),
(69, '鸡蛋', '3个', 1),(69, '面粉', '100克', 1),(69, '', '2根', 0),(69, '', '适量', 0),
(70, '小米', '100克', 1),(70, '南瓜', '200克', 1),(70, '', '少许', 0),
(71, '饺子', '15个', 1),(71, '', '适量', 0),(71, '', '蘸料', 0),
(72, '吐司', '4片', 1),(72, '鸡蛋', '1个', 1),(72, '火腿', '2片', 1),(72, '生菜', '2片', 0),(72, '番茄', '1个', 0),(72, '沙拉酱', '适量', 0),
(73, '面粉', '200克', 1),(73, '黄豆', '100克', 1),(73, '酵母', '2克', 0),(73, '泡打粉', '1克', 0),(73, '', '适量', 0),(73, '', '适量', 0),
(74, '猪肉末', '200克', 1),(74, '馄饨皮', '30张', 1),(74, '虾皮', '适量', 0),(74, '紫菜', '适量', 0),(74, '', '2片', 0),(74, '生抽', '1勺', 0),(74, '料酒', '1勺', 0),(74, '', '适量', 0),(74, '香油', '少许', 0),
(75, '五花肉', '500克', 1),(75, '面粉', '300克', 1),(75, '酵母', '3克', 0),(75, '', '3片', 0),(75, '生抽', '2勺', 0),(75, '老抽', '1勺', 0),(75, '料酒', '1勺', 0),(75, '', '适量', 0),
(76, '糯米', '200克', 1),(76, '鸡腿肉', '150克', 1),(76, '干香菇', '5朵', 0),(76, '生抽', '1勺', 0),(76, '蚝油', '1勺', 0),(76, '', '适量', 0),
(77, '面粉', '150克', 1),(77, '鸡蛋', '2个', 1),(77, '薄脆', '2片', 0),(77, '生菜', '2片', 0),(77, '', '1根', 0),(77, '甜面酱', '适量', 0),(77, '辣椒酱', '适量', 0),(77, '', '适量', 0),
(78, '面粉', '200克', 1),(78, '红豆沙', '150克', 1),(78, '酵母', '2克', 0),(78, '', '20克', 0);
-- 汤羹类 (79-86)
INSERT INTO recipe_ingredients (recipe_id, ingredient_name, amount, is_staple) VALUES
(79, '番茄', '2个', 1),(79, '鸡蛋', '2个', 1),(79, '', '适量', 0),(79, '香油', '少许', 0),
(80, '紫菜', '适量', 1),(80, '鸡蛋', '2个', 1),(80, '虾皮', '少许', 0),(80, '', '适量', 0),(80, '香油', '少许', 0),
(81, '排骨', '300克', 1),(81, '玉米', '2根', 1),(81, '胡萝卜', '1根', 0),(81, '', '3片', 0),(81, '', '适量', 0),(81, '料酒', '1勺', 0),
(82, '牛肉末', '100克', 1),(82, '豆腐', '1块', 0),(82, '鸡蛋清', '1个', 0),(82, '香菜', '适量', 0),(82, '', '2片', 0),(82, '淀粉', '适量', 0),(82, '', '适量', 0),(82, '香油', '少许', 0),
(83, '豆腐', '1块', 1),(83, '木耳', '适量', 0),(83, '鸡蛋', '1个', 0),(83, '', '2勺', 0),(83, '白胡椒粉', '1勺', 0),(83, '淀粉', '适量', 0),(83, '', '适量', 0),(83, '香油', '少许', 0),
(84, '鲫鱼', '1条', 1),(84, '豆腐', '1块', 1),(84, '', '5片', 0),(84, '', '2根', 0),(84, '料酒', '1勺', 0),(84, '', '适量', 0),
(85, '排骨', '300克', 1),(85, '莲藕', '1节', 1),(85, '', '3片', 0),(85, '', '适量', 0),(85, '料酒', '1勺', 0),
(86, '银耳', '1朵', 1),(86, '莲子', '50克', 1),(86, '冰糖', '适量', 0);
-- 凉菜类 (87-94)
INSERT INTO recipe_ingredients (recipe_id, ingredient_name, amount, is_staple) VALUES
(87, '黄瓜', '2根', 1),(87, '', '5瓣', 0),(87, '', '2勺', 0),(87, '生抽', '1勺', 0),(87, '', '适量', 0),(87, '香油', '少许', 0),
(88, '皮蛋', '2个', 1),(88, '豆腐', '1块', 1),(88, '', '3瓣', 0),(88, '生抽', '1勺', 0),(88, '', '1勺', 0),(88, '香油', '少许', 0),(88, '', '适量', 0),
(89, '木耳', '适量', 1),(89, '', '5瓣', 0),(89, '', '1勺', 0),(89, '生抽', '1勺', 0),(89, '辣椒油', '适量', 0),(89, '', '适量', 0),(89, '香油', '少许', 0),
(90, '黄瓜', '1根', 1),(90, '胡萝卜', '半根', 1),(90, '粉丝', '1把', 1),(90, '', '5瓣', 0),(90, '', '2勺', 0),(90, '生抽', '1勺', 0),(90, '', '适量', 0),(90, '香油', '少许', 0),
(91, '番茄', '2个', 1),(91, '', '2勺', 0),
(92, '鸡胸肉', '200克', 1),(92, '黄瓜', '半根', 0),(92, '', '5瓣', 0),(92, '', '1勺', 0),(92, '生抽', '1勺', 0),(92, '辣椒油', '适量', 0),(92, '', '适量', 0),(92, '香油', '少许', 0),
(93, '黄瓜', '2根', 1),(93, '', '5瓣', 0),(93, '', '2勺', 0),(93, '生抽', '1勺', 0),(93, '', '适量', 0),(93, '辣椒油', '适量', 0),
(94, '海带丝', '200克', 1),(94, '', '5瓣', 0),(94, '', '1勺', 0),(94, '生抽', '1勺', 0),(94, '辣椒油', '适量', 0),(94, '', '适量', 0),(94, '香油', '少许', 0);
-- 主食类 (95-100)
INSERT INTO recipe_ingredients (recipe_id, ingredient_name, amount, is_staple) VALUES
(95, '米饭', '300克', 1),(95, '鸡蛋', '2个', 1),(95, '', '1根', 0),(95, '', '适量', 0),
(96, '面条', '200克', 1),(96, '番茄', '2个', 1),(96, '鸡蛋', '2个', 1),(96, '', '1根', 0),(96, '', '适量', 0),(96, '生抽', '1勺', 0),
(97, '面条', '200克', 1),(97, '猪肉末', '150克', 1),(97, '黄豆酱', '1勺', 0),(97, '甜面酱', '1勺', 0),(97, '黄瓜', '半根', 0),(97, '', '2片', 0),(97, '', '3瓣', 0),(97, '料酒', '1勺', 0),
(98, '面条', '200克', 1),(98, '', '5根', 1),(98, '生抽', '2勺', 0),(98, '老抽', '1勺', 0),(98, '', '少许', 0),
(99, '米粉', '200克', 1),(99, '鸡蛋', '2个', 1),(99, '豆芽', '100克', 0),(99, '生抽', '1勺', 0),(99, '', '适量', 0),
(100, '面条', '200克', 1),(100, '', '2根', 0),(100, '生抽', '1勺', 0),(100, '香油', '少许', 0),(100, '', '适量', 0);
-- ============================================================
-- 菜谱步骤数据只列关键步骤每道菜3-4步
-- ============================================================
INSERT INTO recipe_steps (recipe_id, step_order, content) VALUES
(1,1,'西红柿洗净切块,鸡蛋打散加少许盐搅匀'),(1,2,'热锅凉油,倒入蛋液划散盛出'),(1,3,'锅留底油爆香葱,下西红柿翻炒出汁'),(1,4,'倒入鸡蛋,加糖和盐调味,翻炒均匀出锅'),
(2,1,'土豆去皮切细丝,冷水浸泡去淀粉后沥干'),(2,2,'热锅凉油爆香干辣椒和花椒'),(2,3,'下土豆丝大火翻炒,加醋和盐调味'),(2,4,'炒至土豆丝断生即可出锅'),
(3,1,'猪肉切丝加料酒、生抽、淀粉腌制10分钟'),(3,2,'青椒切丝,姜蒜切末'),(3,3,'热油滑炒肉丝至变色盛出'),(3,4,'爆香姜蒜下青椒翻炒,倒回肉丝加调料炒匀'),
(4,1,'西兰花掰小朵焯水1分钟捞出'),(4,2,'蒜切末热油爆香'),(4,3,'下西兰花大火快炒,加蚝油和盐调味'),
(5,1,'里脊肉切条加蛋液、盐、淀粉腌制'),(5,2,'六成油温炸至金黄捞出,再复炸至酥脆'),(5,3,'番茄酱、糖、醋、水调成糖醋汁'),(5,4,'锅留底油倒入糖醋汁熬至浓稠,倒肉条裹匀'),
(6,1,'四季豆去筋掰段焯水沥干'),(6,2,'热油爆香干辣椒、花椒和蒜末'),(6,3,'下四季豆大火煸炒至表面起皱'),(6,4,'加盐调味炒匀出锅'),
(7,1,'鸡翅表面划刀焯水去血沫'),(7,2,'热油煎鸡翅至两面金黄'),(7,3,'加姜片、料酒、生抽翻炒'),(7,4,'倒入可乐没过鸡翅,中火炖至汤汁浓稠'),
(8,1,'韭黄洗净切段,鸡蛋打散'),(8,2,'热油炒鸡蛋至凝固盛出'),(8,3,'锅中炒韭黄至变软,倒回鸡蛋加盐炒匀'),
(9,1,'豆腐切块焯水去豆腥味'),(9,2,'热油爆香蒜末加生抽蚝油'),(9,3,'加少量水放入豆腐中火炖5分钟'),(9,4,'加糖和盐调味大火收汁出锅'),
(10,1,'生菜洗净掰开焯水5秒捞出摆盘'),(10,2,'蒜切末热油爆香加蚝油略炒'),(10,3,'浇在生菜上即可'),
(11,1,'土豆去皮切片,热油煎至两面金黄'),(11,2,'撒孜然粉、辣椒粉和盐'),(11,3,'翻匀出锅'),
(12,1,'洋葱切丝,猪肉切片加料酒生抽腌制'),(12,2,'热油炒肉片至变色盛出'),(12,3,'炒洋葱至变软倒回肉片加盐炒匀'),
(13,1,'香菇泡发切片,油菜焯水备用'),(13,2,'热油爆香蒜末下香菇翻炒'),(13,3,'加蚝油和盐调味'),(13,4,'放入油菜翻匀出锅'),
(14,1,'豆腐切块煎至两面金黄'),(14,2,'青椒和木耳炒香'),(14,3,'加生抽蚝油和少量水放入豆腐炖3分钟'),(14,4,'加盐调味收汁出锅'),
(15,1,'猪肉切丝加料酒腌制,雪菜切碎'),(15,2,'热油下姜片炒肉丝至变色'),(15,3,'加雪菜翻炒加盐调味出锅'),
(16,1,'豆芽洗净沥干'),(16,2,'热油爆香蒜末和干辣椒'),(16,3,'下豆芽大火快炒加醋和盐,断生即出锅'),
(17,1,'芹菜切段焯水,香干切片'),(17,2,'热油爆香蒜末下香干煸炒'),(17,3,'加芹菜翻炒加生抽和盐调味'),
(18,1,'番茄切块,菜花掰小朵焯水'),(18,2,'热油下番茄翻炒出汁'),(18,3,'加菜花翻炒加盐和糖调味'),
(19,1,'茄子切滚刀块加盐腌制挤水'),(19,2,'热油煸炒茄条至软盛出'),(19,3,'爆香姜蒜加肉末炒至变色'),(19,4,'加生抽蚝油倒回茄子翻炒收汁'),
(20,1,'羊肉切片加料酒生抽腌制'),(20,2,'大葱斜刀切片'),(20,3,'热油爆香姜片下羊肉大火快炒'),(20,4,'羊肉变色后加葱片、孜然粉和盐快速翻炒出锅'),
(21,1,'豆腐切块焯水备用'),(21,2,'热油炒肉末至变色加豆瓣酱炒出红油'),(21,3,'加姜蒜末和适量水放入豆腐中火炖5分钟'),(21,4,'撒花椒粉出锅'),
(22,1,'五花肉冷水下锅加姜料酒煮至八成熟切片'),(22,2,'热锅少油煸炒肉片至卷曲出油'),(22,3,'加豆瓣酱姜蒜炒出红油'),(22,4,'加蒜苗段和生抽翻炒至蒜苗断生'),
(23,1,'鸡胸肉切丁加料酒淀粉腌制,花生米油炸备用'),(23,2,'调酱汁:生抽+醋+糖+淀粉+水'),(23,3,'热油爆香干辣椒花椒姜蒜下鸡丁滑炒'),(23,4,'倒酱汁翻炒至浓稠加花生米翻匀'),
(24,1,'猪肉切片加淀粉料酒腌制'),(24,2,'热油爆香豆瓣酱姜蒜干辣椒花椒'),(24,3,'加水煮沸下白菜豆芽煮熟捞出铺碗底'),(24,4,'肉片下锅滑熟连汤倒入碗中,表面撒干辣椒花椒淋热油'),
(25,1,'猪肉切丝加料酒淀粉腌制'),(25,2,'调鱼香汁:生抽+醋+糖+淀粉+水'),(25,3,'木耳胡萝卜青椒切丝,热油爆香豆瓣酱姜蒜'),(25,4,'下肉丝滑炒加配菜倒鱼香汁炒匀'),
(26,1,'鸡腿肉切丁加料酒生抽淀粉腌制'),(26,2,'干辣椒剪段,热油炸鸡丁至金黄捞出'),(26,3,'锅留底油爆香干辣椒花椒姜蒜'),(26,4,'倒回鸡丁快速翻炒加盐出锅'),
(27,1,'牛腱子和牛肚加姜料酒卤煮至熟烂切片'),(27,2,'调汁:辣椒油+花椒粉+蒜泥+生抽+醋+糖'),(27,3,'浇在肉片上撒花生碎和香菜'),
(28,1,'鸡腿加姜葱料酒煮熟捞出冰水过凉'),(28,2,'斩块摆盘'),(28,3,'调汁:辣椒油+花椒粉+蒜泥+生抽+醋+糖'),(28,4,'浇汁撒花生碎和葱花'),
(29,1,'牛肉切丝加料酒生抽腌制'),(29,2,'芹菜切段,干辣椒剪段'),(29,3,'热油爆香干辣椒姜蒜下牛肉丝煸炒'),(29,4,'加芹菜翻炒加盐出锅'),
(30,1,'五花肉加姜片料酒冷水煮熟切片摆盘'),(30,2,'调汁:蒜泥+生抽+醋+辣椒油+糖'),(30,3,'浇在肉片上即可'),
(31,1,'草鱼片加料酒盐淀粉腌制,酸菜切丝'),(31,2,'热油炒酸菜加姜蒜干辣椒花椒'),(31,3,'加水煮沸下鱼片滑熟'),(31,4,'表面撒干辣椒花椒淋热油'),
(32,1,'鸭血毛肚午餐肉切片焯水'),(32,2,'热油爆香豆瓣酱姜蒜干辣椒花椒'),(32,3,'加水煮沸下所有食材煮5分钟'),(32,4,'撒蒜末淋热油'),
(33,1,'虾去虾线藕土豆切片焯水'),(33,2,'热油爆香豆瓣酱姜蒜干辣椒花椒'),(33,3,'下所有食材大火翻炒加生抽'),(33,4,'炒至入味撒芝麻出锅'),
(34,1,'鸡爪剪指甲对半切开焯水'),(34,2,'加姜蒜料酒煮熟捞出'),(34,3,'泡椒连水加白醋和盐调成泡汁'),(34,4,'鸡爪浸入泡汁冷藏4小时以上'),
(35,1,'面条煮熟过凉水沥干'),(35,2,'芝麻酱调稀加生抽醋蒜泥辣椒油花椒粉'),(35,3,'猪肉末炒香加调料做臊子'),(35,4,'面条拌酱撒臊子和葱花'),
(36,1,'整鸡处理干净加姜葱料酒冷水煮开'),(36,2,'转小火浸煮20分钟至熟'),(36,3,'捞出冰水浸泡使皮爽滑'),(36,4,'斩块摆盘配姜葱油蘸料'),
(37,1,'鲈鱼处理干净两侧划刀抹盐和料酒'),(37,2,'鱼身铺姜片葱段'),(37,3,'水开上锅大火蒸8-10分钟'),(37,4,'倒掉蒸汁淋蒸鱼豉油,热油浇在鱼身上'),
(38,1,'虾洗净剪去虾须挑虾线'),(38,2,'水加姜片料酒烧开下虾'),(38,3,'煮至虾变红弯曲即可捞出摆盘'),
(39,1,'梅花肉加叉烧酱生抽料酒姜蒜腌制4小时'),(39,2,'烤箱200度烤15分钟取出刷蜂蜜'),(39,3,'翻面再烤15分钟至表面焦香'),(39,4,'切片装盘'),
(40,1,'里脊肉切丁加蛋液盐淀粉腌,菠萝青椒切块'),(40,2,'六成油温炸肉至金黄捞出'),(40,3,'番茄酱糖醋水调汁熬浓'),(40,4,'倒肉和菠萝青椒翻炒裹匀'),
(41,1,'牛肉切片加生抽料酒淀粉腌制'),(41,2,'河粉抖散热油炒至微焦盛出'),(41,3,'热油爆炒牛肉至变色加豆芽'),(41,4,'倒回河粉加生抽老抽大火翻炒均匀撒葱'),
(42,1,'粉丝温水泡软扇贝洗净'),(42,2,'蒜切末热油炸至金黄加生抽蚝油'),(42,3,'扇贝上铺粉丝和蒜蓉'),(42,4,'水开上锅大火蒸5分钟'),
(43,1,'排骨斩小块加所有调料腌制30分钟'),(43,2,'码入盘中'),(43,3,'水开上锅大火蒸15-20分钟'),
(44,1,'大米泡30分钟排骨腌制腊肠切片'),(44,2,'砂锅抹油放米加水大火煮开'),(44,3,'水快干时铺排骨腊肠转小火焖15分钟'),(44,4,'沿锅边淋油续焖3分钟加焯水油菜淋生抽蚝油'),
(45,1,'排骨焯水去血沫'),(45,2,'冬瓜去皮切大块'),(45,3,'排骨加姜片料酒足量水大火煮开转小火炖40分钟'),(45,4,'加冬瓜续炖15分钟加盐调味'),
(46,1,'牛肉切片加料酒生抽淀粉腌制'),(46,2,'青椒切块,热油滑牛肉至变色盛出'),(46,3,'爆香姜蒜下青椒翻炒'),(46,4,'倒回牛肉加蚝油翻炒均匀出锅'),
(47,1,'虾仁切粒加调料拌匀做馅'),(47,2,'澄粉加淀粉开水烫面揉匀'),(47,3,'擀皮包入虾馅捏成饺子形'),(47,4,'水开上锅大火蒸8分钟'),
(48,1,'大米提前泡好磨成米浆'),(48,2,'平盘刷油倒薄薄一层米浆'),(48,3,'撒虾仁或牛肉碎上锅蒸2分钟'),(48,4,'刮起装盘淋生抽'),
(49,1,'面粉加酵母糖温水和面发酵至2倍大'),(49,2,'叉烧肉切小丁加蚝油生抽调馅'),(49,3,'面团分剂子包入叉烧馅'),(49,4,'二次发酵后上锅大火蒸12分钟'),
(50,1,'鸡蛋打散加糖牛奶搅匀过筛'),(50,2,'倒入蛋挞皮八分满'),(50,3,'烤箱200度烤15-20分钟至表面微焦'),
(51,1,'鱼头处理干净抹盐料酒腌制'),(51,2,'盘中铺姜葱放鱼头'),(51,3,'铺满剁椒上锅大火蒸10-12分钟'),(51,4,'倒掉蒸汁淋蒸鱼豉油,热油浇在剁椒上'),
(52,1,'五花肉切薄片青椒斜刀切圈'),(52,2,'热锅少油煸五花肉至出油卷曲'),(52,3,'加姜蒜爆香加青椒大火翻炒'),(52,4,'加生抽和盐炒至青椒断生'),
(53,1,'酸豆角切粒猪肉剁末'),(53,2,'热油炒肉末至变色加姜蒜干辣椒'),(53,3,'加酸豆角翻炒加生抽和盐'),
(54,1,'腊肉腊鱼温水洗净切片'),(54,2,'码入盘中加姜蒜干辣椒和料酒'),(54,3,'上锅大火蒸20分钟'),
(55,1,'花菜掰小朵焯水,五花肉切薄片'),(55,2,'热锅少油煸五花肉出油'),(55,3,'加干辣椒和蒜爆香下花菜翻炒'),(55,4,'加生抽和盐翻炒至花菜入味'),
(56,1,'小龙虾刷净去虾线焯水'),(56,2,'热油爆香豆瓣酱姜蒜干辣椒花椒'),(56,3,'下小龙虾翻炒加生抽料酒糖和适量水'),(56,4,'中火焖煮15分钟收汁'),
(57,1,'青椒直接放火上烤至表皮焦黑'),(57,2,'去皮撕成条'),(57,3,'皮蛋剥壳切瓣摆盘'),(57,4,'加蒜泥生抽醋盐拌匀'),
(58,1,'猪肉剁末萝卜干泡发切碎'),(58,2,'热油炒肉末至变色加姜蒜干辣椒'),(58,3,'加萝卜干翻炒加生抽和盐'),
(59,1,'里脊肉切厚片用刀背拍松加盐料酒腌制'),(59,2,'淀粉加水调糊肉片裹糊六成油温炸至金黄'),(59,3,'复炸至酥脆捞出'),(59,4,'糖醋水调汁熬浓倒肉片快速翻匀'),
(60,1,'土豆茄子青椒切滚刀块'),(60,2,'分别油炸:土豆炸金黄茄子炸软青椒过油'),(60,3,'爆香蒜末加生抽糖盐和少许水'),(60,4,'倒入所有食材翻炒均匀勾薄芡'),
(61,1,'五花肉切块焯水粉条泡软'),(61,2,'热锅少油煸五花肉至出油加姜蒜生抽老抽料酒'),(61,3,'加足量水大火煮开转小火炖30分钟'),(61,4,'加粉条和白菜续炖10分钟加盐调味'),
(62,1,'排骨焯水土豆切块豆角掰段玉米切段'),(62,2,'热油爆香姜片下排骨翻炒'),(62,3,'加生抽和足量水大火煮沸转小火炖20分钟'),(62,4,'加土豆豆角玉米续炖20分钟加盐'),
(63,1,'里脊肉切丝加生抽料酒淀粉腌制'),(63,2,'热油滑炒肉丝至变色盛出'),(63,3,'锅中炒甜面酱加糖和少许水'),(63,4,'倒回肉丝翻炒裹匀酱汁配葱丝和豆腐皮'),
(64,1,'地瓜去皮切滚刀块'),(64,2,'六成油温炸地瓜至金黄熟透捞出'),(64,3,'另起锅加糖和少量水小火熬至琥珀色'),(64,4,'迅速倒入地瓜块翻匀拉丝装盘'),
(65,1,'五花肉切大块焯水酸菜切丝'),(65,2,'热锅少油煸五花肉至出油加姜蒜料酒'),(65,3,'加足量水大火煮开转小火炖30分钟'),(65,4,'加酸菜续炖20分钟加盐'),
(66,1,'里脊肉切条加料酒盐腌制,淀粉加水调糊'),(66,2,'肉条裹糊六成油温炸至金黄捞出复炸'),(66,3,'调汁:生抽+糖+醋+淀粉+水'),(66,4,'爆香姜蒜下青椒胡萝卜倒汁熬浓加肉条翻匀'),
(67,1,'面粉加水和少许盐揉成光滑面团醒30分钟'),(67,2,'擀成薄饼刷油撒葱花'),(67,3,'卷起盘成圆饼再擀薄'),(67,4,'平底锅刷油中小火烙至两面金黄打入鸡蛋摊匀'),
(68,1,'大米泡30分钟加水大火煮开转小火'),(68,2,'皮蛋切丁猪肉末加料酒腌制'),(68,3,'粥熬至米粒开花加肉末皮蛋姜丝搅匀'),(68,4,'续煮5分钟加盐调味'),
(69,1,'鸡蛋打散加面粉盐和水搅成面糊'),(69,2,'平底锅刷油倒入面糊摊平'),(69,3,'中小火煎至底面金黄翻面'),(69,4,'煎至两面金黄撒葱花出锅切块'),
(70,1,'小米洗净南瓜去皮切小块'),(70,2,'加水大火煮开转小火'),(70,3,'熬25分钟至小米和南瓜软烂'),(70,4,'根据口味加少许糖'),
(71,1,'饺子提前包好或冷冻饺子'),(71,2,'平底锅刷油摆入饺子'),(71,3,'加没过饺子三分之一的水加盖中火煎'),(71,4,'水干后改小火煎至底部金黄酥脆'),
(72,1,'吐司去边鸡蛋打散煎成蛋皮'),(72,2,'吐司上依次铺生菜火腿番茄蛋皮'),(72,3,'挤沙拉酱盖上另一片吐司'),(72,4,'对角切开成三角形'),
(73,1,'黄豆泡发打豆浆过滤煮沸'),(73,2,'面粉加酵母泡打粉盐糖和面发酵'),(73,3,'面团分剂子擀成长条入油锅炸至金黄蓬松'),(73,4,'配豆浆食用'),
(74,1,'猪肉末加生抽料酒姜末盐和少许水调馅'),(74,2,'馄饨皮包入馅料捏紧'),(74,3,'水开下馄饨煮至浮起'),(74,4,'碗底放虾皮紫菜盐香油加汤盛入馄饨'),
(75,1,'五花肉切大块焯水加生抽老抽料酒姜炖烂'),(75,2,'面粉加酵母温水和面发酵至2倍大'),(75,3,'面团分剂子擀饼烙至两面微黄'),(75,4,'肉剁碎夹入饼中浇少许肉汁'),
(76,1,'糯米泡4小时鸡腿肉切丁加生抽蚝油腌制'),(76,2,'香菇泡发切丁热油爆香'),(76,3,'加鸡肉炒变色倒入糯米翻炒'),(76,4,'加盐调味包入荷叶上锅蒸40分钟'),
(77,1,'面粉加盐和水调成面糊醒20分钟'),(77,2,'平底锅抹薄薄一层面糊打入鸡蛋摊匀撒葱'),(77,3,'翻面刷甜面酱和辣椒酱'),(77,4,'放薄脆和生菜卷起即可'),
(78,1,'面粉加酵母糖温水和面发酵至2倍大'),(78,2,'面团分剂子擀皮包入红豆沙'),(78,3,'收口朝下二次发酵15分钟'),(78,4,'上锅大火蒸12分钟焖3分钟开盖'),
(79,1,'番茄切块鸡蛋打散'),(79,2,'热油下番茄翻炒出汁加适量水煮开'),(79,3,'淋入蛋液搅成蛋花'),(79,4,'加盐和香油调味出锅'),
(80,1,'紫菜撕碎鸡蛋打散'),(80,2,'水烧开下紫菜和虾皮'),(80,3,'淋入蛋液搅成蛋花'),(80,4,'加盐和香油出锅'),
(81,1,'排骨焯水玉米切段胡萝卜切滚刀块'),(81,2,'排骨加姜片料酒足量水大火煮开转小火炖40分钟'),(81,3,'加玉米和胡萝卜续炖20分钟'),(81,4,'加盐调味出锅'),
(82,1,'牛肉末加蛋清淀粉少许盐拌匀'),(82,2,'豆腐切小丁焯水'),(82,3,'水加姜片煮开下牛肉滑散'),(82,4,'加豆腐煮3分钟勾薄芡加盐香油撒香菜'),
(83,1,'豆腐切丝木耳切丝鸡蛋打散'),(83,2,'水加姜片煮开下豆腐木耳'),(83,3,'加醋白胡椒粉和盐调味'),(83,4,'淋蛋液勾芡加香油出锅'),
(84,1,'鲫鱼处理干净两面划刀抹盐料酒'),(84,2,'热油煎鲫鱼至两面微黄'),(84,3,'加姜片和足量开水大火煮10分钟至汤变白'),(84,4,'加豆腐块续煮5分钟加盐撒葱'),
(85,1,'排骨焯水莲藕去皮切滚刀块'),(85,2,'排骨加姜片料酒足量水大火煮开转小火炖40分钟'),(85,3,'加莲藕续炖20分钟'),(85,4,'加盐调味出锅'),
(86,1,'银耳泡发撕小朵莲子去芯泡发'),(86,2,'银耳和莲子放入锅中加足量水'),(86,3,'大火煮开转小火熬40分钟至银耳出胶'),(86,4,'加冰糖搅拌融化即可'),
(87,1,'黄瓜洗净用刀拍裂切段'),(87,2,'蒜切末加生抽醋盐调汁'),(87,3,'浇在黄瓜上拌匀淋香油'),
(88,1,'皮蛋剥壳切瓣豆腐切块'),(88,2,'豆腐垫底皮蛋摆上面'),(88,3,'调汁:蒜末+生抽+醋+香油+盐'),(88,4,'浇汁即可'),
(89,1,'木耳泡发洗净焯水2分钟过凉'),(89,2,'调汁:蒜末+生抽+醋+辣椒油+盐+香油'),(89,3,'浇在木耳上拌匀'),
(90,1,'黄瓜胡萝卜切丝粉丝泡软焯水'),(90,2,'调汁:蒜末+生抽+醋+盐+香油'),(90,3,'所有食材混合浇汁拌匀'),
(91,1,'番茄洗净切块'),(91,2,'撒白糖拌匀即可'),
(92,1,'鸡胸肉加姜片料酒煮熟撕成丝'),(92,2,'黄瓜切丝'),(92,3,'调汁:蒜末+生抽+醋+辣椒油+盐+香油'),(92,4,'鸡丝和黄瓜混合浇汁拌匀'),
(93,1,'黄瓜洗净用刀拍裂切段'),(93,2,'蒜切末加生抽醋盐辣椒油调汁'),(93,3,'浇在黄瓜上拌匀'),
(94,1,'海带丝焯水过凉'),(94,2,'调汁:蒜末+生抽+醋+辣椒油+盐+香油'),(94,3,'浇在海带丝上拌匀'),
(95,1,'鸡蛋打散,葱切末'),(95,2,'热油炒鸡蛋划散盛出'),(95,3,'锅中放米饭炒散加鸡蛋翻炒'),(95,4,'加盐和葱末翻炒均匀出锅'),
(96,1,'番茄切块鸡蛋打散'),(96,2,'热油炒鸡蛋盛出,炒番茄出汁加水煮开'),(96,3,'下面条煮熟'),(96,4,'倒回鸡蛋加盐生抽调味撒葱花'),
(97,1,'猪肉剁末,热油炒肉末至变色加姜蒜'),(97,2,'加黄豆酱和甜面酱翻炒加料酒和少许水熬煮'),(97,3,'面条煮熟过凉沥干盛碗'),(97,4,'码上肉酱和黄瓜丝拌匀'),
(98,1,'葱切段热油炸至金黄焦香得葱油'),(98,2,'面碗底加生抽老抽糖'),(98,3,'面条煮熟捞入碗中'),(98,4,'淋上葱油拌匀'),
(99,1,'米粉泡软沥干鸡蛋打散'),(99,2,'热油炒鸡蛋盛出,炒豆芽'),(99,3,'下米粉翻炒加生抽和盐'),(99,4,'倒回鸡蛋翻炒均匀出锅'),
(100,1,'面条煮熟捞入碗中'),(100,2,'加生抽盐香油调味'),(100,3,'撒上葱花浇上面汤即可');

View File

@@ -0,0 +1,49 @@
-- ============================================================
-- 100道菜谱食材数据
-- ============================================================
USE chowbox;
-- 家常快手菜食材
INSERT INTO recipe_ingredients (recipe_id, ingredient_name, amount, is_staple) VALUES
-- 1. 西红柿炒鸡蛋
(1, '西红柿', '2个', 1),(1, '鸡蛋', '3个', 1),(1, '', '1根', 0),(1, '', '适量', 0),(1, '', '少许', 0),(1, '', '适量', 0),
-- 2. 酸辣土豆丝
(2, '土豆', '2个', 1),(2, '干辣椒', '3个', 0),(2, '花椒', '少许', 0),(2, '', '1勺', 0),(2, '', '适量', 0),(2, '', '1根', 0),(2, '', '适量', 0),
-- 3. 青椒肉丝
(3, '猪里脊', '200克', 1),(3, '青椒', '3个', 1),(3, '', '3片', 0),(3, '', '2瓣', 0),(3, '生抽', '1勺', 0),(3, '料酒', '1勺', 0),(3, '淀粉', '1勺', 0),(3, '', '适量', 0),(3, '', '适量', 0),
-- 4. 蒜蓉西兰花
(4, '西兰花', '1颗', 1),(4, '', '5瓣', 0),(4, '', '适量', 0),(4, '蚝油', '1勺', 0),(4, '', '适量', 0),
-- 5. 糖醋里脊
(5, '猪里脊', '300克', 1),(5, '鸡蛋', '1个', 0),(5, '面粉', '50克', 0),(5, '番茄酱', '2勺', 0),(5, '白糖', '2勺', 0),(5, '白醋', '1勺', 0),(5, '', '适量', 0),(5, '', '适量', 0),
-- 6. 干煸四季豆
(6, '四季豆', '300克', 1),(6, '猪肉末', '50克', 0),(6, '干辣椒', '3个', 0),(6, '花椒', '少许', 0),(6, '', '3瓣', 0),(6, '生抽', '1勺', 0),(6, '', '适量', 0),(6, '', '适量', 0),
-- 7. 可乐鸡翅
(7, '鸡翅中', '8个', 1),(7, '可乐', '1罐', 0),(7, '生抽', '2勺', 0),(7, '老抽', '半勺', 0),(7, '', '3片', 0),(7, '料酒', '1勺', 0),(7, '', '少许', 0),(7, '', '适量', 0),
-- 8. 韭黄炒蛋
(8, '韭黄', '200克', 1),(8, '鸡蛋', '3个', 1),(8, '', '适量', 0),(8, '', '适量', 0),
-- 9. 红烧豆腐
(9, '老豆腐', '1块', 1),(9, '', '2根', 0),(9, '', '3片', 0),(9, '', '2瓣', 0),(9, '生抽', '2勺', 0),(9, '老抽', '半勺', 0),(9, '豆瓣酱', '1勺', 0),(9, '', '少许', 0),(9, '淀粉', '1勺', 0),(9, '', '适量', 0),
-- 10. 蚝油生菜
(10, '生菜', '1颗', 1),(10, '', '3瓣', 0),(10, '蚝油', '2勺', 0),(10, '生抽', '1勺', 0),(10, '', '适量', 0);
INSERT INTO recipe_ingredients (recipe_id, ingredient_name, amount, is_staple) VALUES
-- 11. 孜然土豆片
(11, '土豆', '2个', 1),(11, '孜然粉', '1勺', 0),(11, '辣椒粉', '半勺', 0),(11, '', '适量', 0),(11, '', '1根', 0),(11, '', '适量', 0),
-- 12. 洋葱炒肉
(12, '洋葱', '1个', 1),(12, '猪肉片', '150克', 1),(12, '生抽', '1勺', 0),(12, '料酒', '1勺', 0),(12, '', '适量', 0),(12, '', '适量', 0),
-- 13. 香菇油菜
(13, '油菜', '5棵', 1),(13, '香菇', '6朵', 1),(13, '', '3瓣', 0),(13, '蚝油', '1勺', 0),(13, '', '适量', 0),(13, '', '适量', 0),
-- 14. 家常豆腐
(14, '老豆腐', '1块', 1),(14, '木耳', '10朵', 0),(14, '青椒', '1个', 0),(14, '胡萝卜', '半根', 0),(14, '豆瓣酱', '1勺', 0),(14, '生抽', '1勺', 0),(14, '', '少许', 0),(14, '', '适量', 0),
-- 15. 雪菜肉丝
(15, '雪里蕻', '200克', 1),(15, '猪肉丝', '100克', 1),(15, '干辣椒', '2个', 0),(15, '生抽', '1勺', 0),(15, '料酒', '1勺', 0),(15, '', '适量', 0),(15, '', '适量', 0),
-- 16. 素炒豆芽
(16, '绿豆芽', '300克', 1),(16, '', '1根', 0),(16, '', '适量', 0),(16, '', '少许', 0),(16, '', '适量', 0),
-- 17. 芹菜香干
(17, '芹菜', '200克', 1),(17, '豆干', '3块', 1),(17, '生抽', '1勺', 0),(17, '', '适量', 0),(17, '', '适量', 0),
-- 18. 番茄菜花
(18, '菜花', '半颗', 1),(18, '西红柿', '1个', 1),(18, '番茄酱', '1勺', 0),(18, '', '适量', 0),(18, '', '少许', 0),(18, '', '适量', 0),
-- 19. 肉末茄子
(19, '长茄子', '2根', 1),(19, '猪肉末', '100克', 1),(19, '', '3瓣', 0),(19, '', '2片', 0),(19, '生抽', '2勺', 0),(19, '老抽', '半勺', 0),(19, '郫县豆瓣酱', '1勺', 0),(19, '', '少许', 0),(19, '料酒', '1勺', 0),(19, '', '适量', 0),
-- 20. 葱爆羊肉
(20, '羊肉片', '250克', 1),(20, '大葱', '2根', 1),(20, '生抽', '2勺', 0),(20, '料酒', '1勺', 0),(20, '孜然粉', '半勺', 0),(20, '', '适量', 0),(20, '', '适量', 0);

View File

@@ -0,0 +1,46 @@
-- 川菜 + 粤菜食材数据
USE chowbox;
INSERT INTO recipe_ingredients (recipe_id, ingredient_name, amount, is_staple) VALUES
-- 21. 麻婆豆腐
(21, '嫩豆腐', '1块', 1),(21, '猪肉末', '80克', 0),(21, '郫县豆瓣酱', '1.5勺', 0),(21, '花椒粉', '半勺', 0),(21, '辣椒面', '半勺', 0),(21, '豆豉', '少许', 0),(21, '', '2瓣', 0),(21, '淀粉', '1勺', 0),(21, '', '1根', 0),(21, '', '适量', 0),
-- 22. 回锅肉
(22, '五花肉', '300克', 1),(22, '蒜苗', '3根', 1),(22, '郫县豆瓣酱', '1勺', 0),(22, '生抽', '1勺', 0),(22, '', '3片', 0),(22, '', '2瓣', 0),(22, '料酒', '1勺', 0),(22, '', '少许', 0),(22, '', '适量', 0),
-- 23. 宫保鸡丁
(23, '鸡胸肉', '250克', 1),(23, '花生米', '50克', 0),(23, '黄瓜', '半根', 0),(23, '干辣椒', '5个', 0),(23, '花椒', '少许', 0),(23, '生抽', '1勺', 0),(23, '', '1勺', 0),(23, '', '1勺', 0),(23, '淀粉', '1勺', 0),(23, '', '2瓣', 0),(23, '', '适量', 0),
-- 24. 水煮肉片
(24, '猪里脊', '250克', 1),(24, '豆芽', '100克', 0),(24, '白菜叶', '3片', 0),(24, '郫县豆瓣酱', '2勺', 0),(24, '干辣椒', '10个', 0),(24, '花椒', '适量', 0),(24, '', '5瓣', 0),(24, '料酒', '1勺', 0),(24, '淀粉', '1勺', 0),(24, '', '适量', 0),
-- 25. 鱼香肉丝
(25, '猪里脊', '200克', 1),(25, '木耳', '10朵', 0),(25, '胡萝卜', '半根', 0),(25, '青椒', '1个', 0),(25, '泡椒', '4个', 0),(25, '', '3瓣', 0),(25, '生抽', '1勺', 0),(25, '', '1勺', 0),(25, '', '1勺', 0),(25, '淀粉', '1勺', 0),(25, '郫县豆瓣酱', '半勺', 0),(25, '', '适量', 0),
-- 26. 辣子鸡丁
(26, '鸡腿肉', '300克', 1),(26, '干辣椒', '20个', 0),(26, '花椒', '适量', 0),(26, '', '5片', 0),(26, '', '3瓣', 0),(26, '料酒', '1勺', 0),(26, '生抽', '1勺', 0),(26, '白芝麻', '少许', 0),(26, '', '适量', 0),
-- 27. 夫妻肺片
(27, '牛腱子', '150克', 1),(27, '牛肚', '150克', 1),(27, '花生碎', '30克', 0),(27, '香菜', '2根', 0),(27, '红油', '3勺', 0),(27, '花椒粉', '半勺', 0),(27, '生抽', '2勺', 0),(27, '', '1勺', 0),
-- 28. 口水鸡
(28, '鸡腿', '2个', 1),(28, '花生碎', '30克', 0),(28, '芝麻酱', '1勺', 0),(28, '红油', '2勺', 0),(28, '花椒粉', '半勺', 0),(28, '生抽', '2勺', 0),(28, '', '1勺', 0),(28, '', '3瓣', 0),(28, '', '1根', 0),(28, '香菜', '1根', 0),
-- 29. 干煸牛肉丝
(29, '牛肉', '250克', 1),(29, '芹菜', '100克', 0),(29, '干辣椒', '5个', 0),(29, '花椒', '少许', 0),(29, '', '3片', 0),(29, '郫县豆瓣酱', '1勺', 0),(29, '生抽', '1勺', 0),(29, '料酒', '1勺', 0),(29, '', '适量', 0),
-- 30. 蒜泥白肉
(30, '五花肉', '250克', 1),(30, '黄瓜', '1根', 0),(30, '', '6瓣', 0),(30, '生抽', '2勺', 0),(30, '红油', '1勺', 0),(30, '', '半勺', 0),(30, '', '少许', 0);
INSERT INTO recipe_ingredients (recipe_id, ingredient_name, amount, is_staple) VALUES
-- 31. 酸菜鱼
(31, '草鱼片', '300克', 1),(31, '酸菜', '200克', 1),(31, '泡椒', '5个', 0),(31, '干辣椒', '5个', 0),(31, '花椒', '少许', 0),(31, '', '5片', 0),(31, '', '3瓣', 0),(31, '料酒', '1勺', 0),(31, '淀粉', '1勺', 0),(31, '', '适量', 0),(31, '', '适量', 0),
-- 32. 毛血旺
(32, '鸭血', '200克', 1),(32, '午餐肉', '100克', 1),(32, '毛肚', '100克', 0),(32, '豆芽', '100克', 0),(32, '郫县豆瓣酱', '2勺', 0),(32, '干辣椒', '10个', 0),(32, '花椒', '适量', 0),(32, '', '3瓣', 0),(32, '料酒', '1勺', 0),(32, '', '适量', 0),
-- 33. 麻辣香锅
(33, '', '10只', 1),(33, '土豆', '1个', 0),(33, '', '半节', 0),(33, '西兰花', '半颗', 0),(33, '香菇', '5朵', 0),(33, '火锅底料', '50克', 0),(33, '干辣椒', '8个', 0),(33, '花椒', '适量', 0),(33, '', '3瓣', 0),(33, '', '适量', 0),
-- 34. 泡椒凤爪
(34, '鸡爪', '500克', 1),(34, '泡椒', '200克', 0),(34, '白醋', '2勺', 0),(34, '', '适量', 0),(34, '料酒', '1勺', 0),(34, '', '5片', 0),
-- 35. 担担面
(35, '面条', '200克', 1),(35, '猪肉末', '80克', 0),(35, '芽菜', '30克', 0),(35, '花生碎', '20克', 0),(35, '芝麻酱', '1勺', 0),(35, '红油', '2勺', 0),(35, '生抽', '1勺', 0),(35, '', '少许', 0),(35, '', '1根', 0),(35, '', '适量', 0),
-- 36. 白切鸡
(36, '三黄鸡', '1只', 1),(36, '', '5片', 0),(36, '', '3根', 0),(36, '料酒', '2勺', 0),(36, '生抽', '3勺', 0),(36, '花生油', '2勺', 0),(36, '', '3瓣', 0),
-- 37. 清蒸鲈鱼
(37, '鲈鱼', '1条', 1),(37, '', '5片', 0),(37, '', '2根', 0),(37, '蒸鱼豉油', '2勺', 0),(37, '料酒', '1勺', 0),(37, '', '适量', 0),
-- 38. 白灼虾
(38, '基围虾', '300克', 1),(38, '', '3片', 0),(38, '料酒', '1勺', 0),(38, '生抽', '2勺', 0),(38, '姜末', '少许', 0),(38, '香油', '少许', 0),
-- 39. 广式叉烧
(39, '猪梅花肉', '500克', 1),(39, '叉烧酱', '4勺', 0),(39, '蜂蜜', '2勺', 0),(39, '生抽', '1勺', 0),(39, '老抽', '半勺', 0),
-- 40. 菠萝咕咾肉
(40, '猪里脊', '250克', 1),(40, '菠萝', '半个', 1),(40, '青椒', '1个', 0),(40, '红椒', '1个', 0),(40, '番茄酱', '3勺', 0),(40, '白醋', '1勺', 0),(40, '', '2勺', 0),(40, '淀粉', '适量', 0),(40, '', '适量', 0);

View File

@@ -0,0 +1,44 @@
-- 粤菜 + 湘菜 + 东北菜 + 早餐 + 汤羹 + 凉菜 + 主食 食材数据
USE chowbox;
INSERT INTO recipe_ingredients (recipe_id, ingredient_name, amount, is_staple) VALUES
-- 41. 干炒牛河
(41, '河粉', '300克', 1),(41, '牛肉片', '150克', 1),(41, '豆芽', '50克', 0),(41, '韭黄', '30克', 0),(41, '生抽', '2勺', 0),(41, '老抽', '半勺', 0),(41, '', '适量', 0),
-- 42. 蒜蓉粉丝蒸扇贝
(42, '扇贝', '6只', 1),(42, '粉丝', '1把', 0),(42, '', '6瓣', 0),(42, '蒸鱼豉油', '1勺', 0),(42, '', '1根', 0),(42, '', '适量', 0),
-- 43. 豉汁蒸排骨
(43, '排骨', '300克', 1),(43, '豆豉', '1勺', 0),(43, '', '3瓣', 0),(43, '生抽', '1勺', 0),(43, '料酒', '1勺', 0),(43, '淀粉', '1勺', 0),(43, '', '少许', 0),
-- 44. 煲仔饭
(44, '大米', '200克', 1),(44, '腊肠', '1根', 0),(44, '腊肉', '50克', 0),(44, '油菜', '3棵', 0),(44, '生抽', '1勺', 0),(44, '', '少许', 0),
-- 45. 冬瓜排骨汤
(45, '排骨', '300克', 1),(45, '冬瓜', '300克', 1),(45, '', '3片', 0),(45, '', '适量', 0),
-- 46. 蚝油牛肉
(46, '牛肉', '250克', 1),(46, '青椒', '1个', 0),(46, '洋葱', '半个', 0),(46, '蚝油', '2勺', 0),(46, '生抽', '1勺', 0),(46, '料酒', '1勺', 0),(46, '淀粉', '1勺', 0),(46, '', '适量', 0),
-- 47. 虾饺
(47, '虾仁', '200克', 1),(47, '猪肥膘', '30克', 0),(47, '澄面', '150克', 0),(47, '生粉', '50克', 0),(47, '竹笋', '30克', 0),(47, '', '适量', 0),
-- 48. 肠粉
(48, '粘米粉', '150克', 1),(48, '鸡蛋', '1个', 0),(48, '猪肉末', '50克', 0),(48, '生菜', '2片', 0),(48, '生抽', '2勺', 0),(48, '', '少许', 0),
-- 49. 叉烧包
(49, '中筋面粉', '300克', 1),(49, '叉烧肉', '200克', 1),(49, '酵母', '3克', 0),(49, '', '20克', 0),(49, '蚝油', '1勺', 0),
-- 50. 蛋挞
(50, '蛋挞皮', '8个', 1),(50, '鸡蛋', '2个', 1),(50, '淡奶油', '100毫升', 0),(50, '牛奶', '100毫升', 0),(50, '', '30克', 0),
-- 51. 剁椒鱼头
(51, '胖头鱼头', '1个', 1),(51, '剁椒', '100克', 0),(51, '', '5片', 0),(51, '', '3瓣', 0),(51, '料酒', '2勺', 0),(51, '蒸鱼豉油', '1勺', 0),(51, '', '1根', 0),(51, '', '适量', 0),
-- 52. 农家小炒肉
(52, '五花肉', '200克', 1),(52, '青椒', '4个', 1),(52, '', '3瓣', 0),(52, '生抽', '1勺', 0),(52, '老抽', '少许', 0),(52, '豆豉', '半勺', 0),(52, '', '适量', 0),
-- 53. 酸豆角肉末
(53, '酸豆角', '200克', 1),(53, '猪肉末', '100克', 1),(53, '干辣椒', '3个', 0),(53, '', '2瓣', 0),(53, '生抽', '1勺', 0),(53, '', '适量', 0),
-- 54. 腊味合蒸
(54, '腊肉', '150克', 1),(54, '腊肠', '1根', 1),(54, '腊鱼', '100克', 0),(54, '豆豉', '1勺', 0),(54, '干辣椒', '2个', 0),(54, '料酒', '1勺', 0),
-- 55. 干锅花菜
(55, '花菜', '半颗', 1),(55, '五花肉片', '80克', 0),(55, '干辣椒', '5个', 0),(55, '', '3瓣', 0),(55, '生抽', '1勺', 0),(55, '郫县豆瓣酱', '半勺', 0),(55, '', '适量', 0),
-- 56. 口味虾
(56, '小龙虾', '500克', 1),(56, '干辣椒', '10个', 0),(56, '花椒', '适量', 0),(56, '', '5瓣', 0),(56, '', '5片', 0),(56, '郫县豆瓣酱', '1勺', 0),(56, '啤酒', '半瓶', 0),(56, '紫苏', '少许', 0),(56, '', '适量', 0),
-- 57. 擂辣椒皮蛋
(57, '青椒', '4个', 1),(57, '皮蛋', '2个', 1),(57, '', '3瓣', 0),(57, '', '1勺', 0),(57, '生抽', '1勺', 0),(57, '香油', '少许', 0),
-- 58. 湘西外婆菜
(58, '酸菜', '200克', 1),(58, '猪肉末', '80克', 0),(58, '干辣椒', '3个', 0),(58, '', '2瓣', 0),(58, '生抽', '1勺', 0),(58, '', '适量', 0),
-- 59. 锅包肉
(59, '猪里脊', '300克', 1),(59, '胡萝卜', '半根', 0),(59, '大葱', '1段', 0),(59, '', '3片', 0),(59, '白醋', '3勺', 0),(59, '白糖', '3勺', 0),(59, '淀粉', '100克', 0),(59, '', '适量', 0),
-- 60. 地三鲜
(60, '茄子', '1根', 1),(60, '土豆', '1个', 1),(60, '青椒', '2个', 1),(60, '', '3瓣', 0),(60, '生抽', '2勺', 0),(60, '老抽', '半勺', 0),(60, '', '少许', 0),(60, '', '适量', 0),(60, '', '适量', 0);

View File

@@ -0,0 +1,43 @@
-- 61-100 剩余食材
USE chowbox;
INSERT INTO recipe_ingredients (recipe_id, ingredient_name, amount, is_staple) VALUES
-- 61. 猪肉炖粉条
(61, '五花肉', '250克', 1),(61, '粉条', '100克', 1),(61, '白菜', '3片', 0),(61, '生抽', '2勺', 0),(61, '老抽', '半勺', 0),(61, '八角', '1个', 0),(61, '', '3片', 0),(61, '', '适量', 0),
-- 62. 东北乱炖
(62, '排骨', '200克', 1),(62, '土豆', '2个', 0),(62, '豆角', '100克', 0),(62, '茄子', '1根', 0),(62, '玉米', '1根', 0),(62, '生抽', '2勺', 0),(62, '老抽', '半勺', 0),(62, '', '适量', 0),(62, '', '适量', 0),
-- 63. 京酱肉丝
(63, '猪里脊', '250克', 1),(63, '大葱', '2根', 0),(63, '豆腐皮', '3张', 0),(63, '甜面酱', '2勺', 0),(63, '生抽', '1勺', 0),(63, '', '少许', 0),(63, '料酒', '1勺', 0),(63, '淀粉', '1勺', 0),(63, '', '适量', 0),
-- 64. 拔丝地瓜
(64, '红薯', '2个', 1),(64, '白糖', '100克', 0),(64, '', '适量', 0),
-- 65. 酸菜白肉
(65, '五花肉', '300克', 1),(65, '东北酸菜', '200克', 1),(65, '粉条', '50克', 0),(65, '', '3片', 0),(65, '八角', '1个', 0),(65, '', '适量', 0),
-- 66. 溜肉段
(66, '猪瘦肉', '250克', 1),(66, '青椒', '1个', 0),(66, '胡萝卜', '半根', 0),(66, '生抽', '2勺', 0),(66, '', '1勺', 0),(66, '', '1勺', 0),(66, '淀粉', '适量', 0),(66, '', '适量', 0),
-- 67. 鸡蛋灌饼
(67, '面粉', '200克', 1),(67, '鸡蛋', '2个', 1),(67, '生菜', '2片', 0),(67, '甜面酱', '1勺', 0),(67, '', '适量', 0),
-- 68. 皮蛋瘦肉粥
(68, '大米', '100克', 1),(68, '皮蛋', '1个', 0),(68, '瘦肉丝', '50克', 0),(68, '', '2片', 0),(68, '', '适量', 0),
-- 69. 葱花鸡蛋饼
(69, '面粉', '150克', 1),(69, '鸡蛋', '2个', 1),(69, '', '2根', 0),(69, '', '适量', 0),(69, '', '适量', 0),
-- 70. 小米南瓜粥
(70, '小米', '100克', 1),(70, '南瓜', '200克', 1),(70, '', '适量', 0),
-- 71. 煎饺
(71, '饺子皮', '20张', 1),(71, '猪肉馅', '200克', 1),(71, '白菜', '100克', 0),(71, '生抽', '1勺', 0),(71, '料酒', '1勺', 0),(71, '', '适量', 0),(71, '', '适量', 0),
-- 72. 三明治
(72, '面包片', '2片', 1),(72, '鸡蛋', '1个', 0),(72, '火腿', '2片', 0),(72, '生菜', '1片', 0),(72, '沙拉酱', '适量', 0),
-- 73. 豆浆油条
(73, '黄豆', '150克', 1),(73, '面粉', '300克', 1),(73, '酵母', '3克', 0),(73, '泡打粉', '3克', 0),(73, '', '适量', 0),
-- 74. 馄饨
(74, '馄饨皮', '30张', 1),(74, '猪肉馅', '200克', 1),(74, '虾仁', '50克', 0),(74, '紫菜', '少许', 0),(74, '虾皮', '少许', 0),(74, '', '1根', 0),(74, '生抽', '1勺', 0),(74, '', '适量', 0),
-- 75. 肉夹馍
(75, '面粉', '300克', 1),(75, '五花肉', '400克', 1),(75, '酵母', '3克', 0),(75, '生抽', '3勺', 0),(75, '老抽', '1勺', 0),(75, '八角', '2个', 0),(75, '桂皮', '1片', 0),(75, '', '3片', 0),
-- 76. 糯米鸡
(76, '糯米', '300克', 1),(76, '鸡腿肉', '200克', 1),(76, '香菇', '5朵', 0),(76, '腊肠', '半根', 0),(76, '生抽', '2勺', 0),(76, '蚝油', '1勺', 0),(76, '荷叶', '2张', 0),
-- 77. 煎饼果子
(77, '面粉', '100克', 1),(77, '绿豆面', '50克', 0),(77, '鸡蛋', '1个', 0),(77, '薄脆', '1片', 0),(77, '甜面酱', '1勺', 0),(77, '辣酱', '适量', 0),(77, '', '少许', 0),(77, '', '少许', 0),
-- 78. 豆沙包
(78, '面粉', '300克', 1),(78, '红豆', '200克', 1),(78, '酵母', '3克', 0),(78, '白糖', '50克', 0),
-- 79. 番茄蛋花汤
(79, '西红柿', '2个', 1),(79, '鸡蛋', '2个', 1),(79, '', '适量', 0),(79, '', '少许', 0),(79, '香油', '几滴', 0),
-- 80. 紫菜蛋花汤
(80, '紫菜', '1片', 1),(80, '鸡蛋', '1个', 1),(80, '', '适量', 0),(80, '香油', '几滴', 0),(80, '虾皮', '少许', 0);

View File

@@ -0,0 +1,23 @@
-- 81-100 + 所有步骤
USE chowbox;
INSERT INTO recipe_ingredients (recipe_id, ingredient_name, amount, is_staple) VALUES
(81, '排骨', '300克', 1),(81, '玉米', '1根', 1),(81, '', '3片', 0),(81, '', '适量', 0),
(82, '牛肉末', '100克', 1),(82, '嫩豆腐', '半块', 0),(82, '鸡蛋清', '1个', 0),(82, '香菜', '少许', 0),(82, '', '适量', 0),(82, '白胡椒粉', '少许', 0),(82, '淀粉', '1勺', 0),
(83, '豆腐', '半块', 0),(83, '木耳', '5朵', 0),(83, '鸡蛋', '1个', 0),(83, '', '2勺', 0),(83, '白胡椒粉', '1勺', 0),(83, '生抽', '1勺', 0),(83, '淀粉', '1勺', 0),(83, '', '适量', 0),(83, '香油', '少许', 0),
(84, '鲫鱼', '1条', 1),(84, '嫩豆腐', '1块', 1),(84, '', '3片', 0),(84, '', '1根', 0),(84, '料酒', '1勺', 0),(84, '', '适量', 0),(84, '', '适量', 0),
(85, '排骨', '300克', 1),(85, '莲藕', '1节', 1),(85, '', '3片', 0),(85, '红枣', '3颗', 0),(85, '', '适量', 0),
(86, '银耳', '1朵', 1),(86, '莲子', '30克', 0),(86, '红枣', '5颗', 0),(86, '冰糖', '适量', 0),
(87, '黄瓜', '2根', 1),(87, '', '3瓣', 0),(87, '', '1勺', 0),(87, '生抽', '1勺', 0),(87, '', '适量', 0),(87, '香油', '少许', 0),(87, '辣椒油', '适量', 0),
(88, '内酯豆腐', '1盒', 1),(88, '皮蛋', '1个', 0),(88, '生抽', '2勺', 0),(88, '', '1勺', 0),(88, '', '少许', 0),(88, '香油', '少许', 0),(88, '', '1根', 0),
(89, '木耳', '20朵', 1),(89, '', '3瓣', 0),(89, '', '1勺', 0),(89, '生抽', '1勺', 0),(89, '', '适量', 0),(89, '辣椒油', '适量', 0),(89, '香油', '少许', 0),
(90, '粉丝', '1把', 1),(90, '黄瓜', '1根', 0),(90, '胡萝卜', '半根', 0),(90, '生抽', '1勺', 0),(90, '', '1勺', 0),(90, '', '2瓣', 0),(90, '', '适量', 0),(90, '辣椒油', '适量', 0),(90, '香油', '少许', 0),
(91, '番茄', '2个', 1),(91, '白糖', '2勺', 0),
(92, '鸡胸肉', '1块', 1),(92, '黄瓜', '半根', 0),(92, '生抽', '1勺', 0),(92, '', '1勺', 0),(92, '', '2瓣', 0),(92, '辣椒油', '1勺', 0),(92, '芝麻酱', '半勺', 0),(92, '', '适量', 0),
(93, '黄瓜', '2根', 1),(93, '', '3瓣', 0),(93, '', '1勺', 0),(93, '生抽', '半勺', 0),(93, '', '适量', 0),(93, '辣椒油', '适量', 0),(93, '香油', '少许', 0),
(94, '海带丝', '200克', 1),(94, '', '2瓣', 0),(94, '', '1勺', 0),(94, '生抽', '1勺', 0),(94, '', '适量', 0),(94, '辣椒油', '适量', 0),(94, '香油', '少许', 0),
(95, '米饭', '1碗', 1),(95, '鸡蛋', '2个', 1),(95, '', '1根', 0),(95, '', '适量', 0),(95, '', '适量', 0),
(96, '面条', '150克', 1),(96, '番茄', '1个', 1),(96, '鸡蛋', '1个', 1),(96, '', '适量', 0),(96, '', '少许', 0),(96, '', '适量', 0),
(97, '面条', '200克', 1),(97, '猪肉末', '100克', 1),(97, '甜面酱', '2勺', 0),(97, '黄豆酱', '1勺', 0),(97, '黄瓜', '1根', 0),(97, '', '1根', 0),(97, '', '适量', 0),
(98, '面条', '150克', 1),(98, '', '4根', 0),(98, '生抽', '2勺', 0),(98, '老抽', '半勺', 0),(98, '', '半勺', 0),(98, '', '适量', 0),
(99, '米粉', '200克', 1),(99, '鸡蛋', '1个', 0),(99, '豆芽', '50克', 0),(99, '火腿', '1根', 0),(99, '生抽', '1勺', 0),(99, '', '适量', 0),
(100, '面条', '100克', 1),(100, '酱油', '1勺', 0),(100, '猪油', '半勺', 0),(100, '', '1根', 0),(100, '', '适量', 0);

View File

@@ -0,0 +1,124 @@
USE chowbox;
-- ============================================================
-- 100道菜谱步骤数据
-- ============================================================
INSERT INTO recipe_steps (recipe_id, step_order, content) VALUES
-- 家常快手菜
(1,1,'鸡蛋打散加少许盐搅匀;西红柿切块备用'),(1,2,'热锅倒油,倒入蛋液炒熟盛出'),(1,3,'锅中再倒少许油,下西红柿炒出汁,加少许糖'),(1,4,'倒回鸡蛋翻炒均匀,加盐调味,撒葱花出锅'),
(2,1,'土豆削皮切细丝,放凉水中浸泡去淀粉'),(2,2,'热锅倒油,下花椒、干辣椒爆香'),(2,3,'大火下土豆丝快速翻炒,加盐、醋'),(2,4,'翻炒2分钟至断生撒葱花出锅'),
(3,1,'猪里脊切丝加料酒、淀粉、生抽腌制10分钟'),(3,2,'青椒切丝,姜蒜切末'),(3,3,'热锅倒油,下肉丝滑炒至变色盛出'),(3,4,'锅中下姜蒜爆香,下青椒翻炒,倒回肉丝,加盐调味出锅'),
(4,1,'西兰花掰小朵焯水1分钟捞出'),(4,2,'蒜切末'),(4,3,'热锅倒油,下蒜末爆香'),(4,4,'下西兰花大火翻炒,加蚝油、盐调味出锅'),
(5,1,'猪里脊切条,加盐、料酒、蛋液腌制'),(5,2,'裹上面粉,油温六成热下锅炸至金黄'),(5,3,'调糖醋汁:番茄酱+糖+白醋+水'),(5,4,'锅中留底油,倒入糖醋汁煮沸,下里脊翻炒裹汁出锅'),
(6,1,'四季豆去筋掰段,焯水后沥干'),(6,2,'热锅多倒油,下四季豆煸至表面起皱盛出'),(6,3,'锅中留底油,下肉末、干辣椒、花椒、蒜炒香'),(6,4,'倒回四季豆,加生抽、盐翻炒均匀出锅'),
(7,1,'鸡翅洗净划两刀,冷水下锅焯水去血沫'),(7,2,'热锅倒少许油,煎鸡翅至两面金黄'),(7,3,'倒入可乐没过鸡翅,加生抽、老抽、姜、料酒'),(7,4,'中火炖15分钟至汤汁收浓加少许盐出锅'),
(8,1,'韭黄洗净切段,鸡蛋打散加盐'),(8,2,'热锅倒油,倒入蛋液炒熟盛出'),(8,3,'锅中再倒油大火下韭黄翻炒1分钟'),(8,4,'倒回鸡蛋炒匀,加盐出锅'),
(9,1,'豆腐切厚片,两面煎至金黄盛出'),(9,2,'锅中下葱姜蒜、豆瓣酱炒出红油'),(9,3,'加入生抽、老抽、糖和半碗水,放入豆腐'),(9,4,'中小火炖5分钟入味水淀粉勾芡撒葱花出锅'),
(10,1,'生菜洗净掰散,蒜切末'),(10,2,'锅中烧水水开焯生菜10秒捞出摆盘'),(10,3,'小碗调汁:蚝油+生抽+少许水搅匀'),(10,4,'热锅少油爆香蒜末,倒入料汁煮开,淋在生菜上'),
-- 11-20
(11,1,'土豆削皮切厚片焯水1分钟捞出沥干'),(11,2,'热锅多倒油,下土豆片煎至两面金黄'),(11,3,'撒入孜然粉、辣椒粉、盐翻炒均匀'),(11,4,'撒葱花出锅'),
(12,1,'洋葱切丝,猪肉切片加料酒、生抽腌制'),(12,2,'热锅倒油,下肉片炒至变色盛出'),(12,3,'锅中下洋葱大火翻炒至半透明'),(12,4,'倒回肉片,加盐调味出锅'),
(13,1,'油菜洗净对半切,香菇去蒂切片'),(13,2,'热锅倒油,下蒜末爆香'),(13,3,'下香菇炒软,再下油菜大火翻炒'),(13,4,'加蚝油、盐调味出锅'),
(14,1,'豆腐切三角片,煎至两面金黄盛出'),(14,2,'木耳泡发洗净,青椒、胡萝卜切片'),(14,3,'锅中下豆瓣酱炒出红油,加生抽和糖'),(14,4,'放入所有食材翻炒加少许水焖2分钟出锅'),
(15,1,'雪里蕻洗净切段,猪肉切丝加料酒腌制'),(15,2,'热锅倒油,下肉丝煸炒至变色'),(15,3,'下干辣椒和雪里蕻大火翻炒'),(15,4,'加生抽、盐调味出锅'),
(16,1,'豆芽洗净沥干,葱切段'),(16,2,'热锅倒油,大火下豆芽快炒'),(16,3,'加盐、少许醋提鲜'),(16,4,'翻炒30秒撒葱段出锅'),
(17,1,'芹菜去叶切段焯水,豆干切条'),(17,2,'热锅倒油,下豆干煎至微黄'),(17,3,'下芹菜大火翻炒'),(17,4,'加生抽、盐调味出锅'),
(18,1,'菜花掰小朵焯水,西红柿切块'),(18,2,'热锅倒油,下西红柿炒出汁'),(18,3,'加入番茄酱和少许糖'),(18,4,'下菜花翻炒均匀,加盐出锅'),
(19,1,'茄子切条撒盐腌制10分钟后挤去水分'),(19,2,'热锅多倒油,下茄子煎软盛出'),(19,3,'锅中下肉末炒香,加姜蒜豆瓣酱炒出红油'),(19,4,'加生抽老抽糖料酒倒回茄子翻炒焖2分钟出锅'),
(20,1,'羊肉片加生抽料酒腌制,大葱切斜段'),(20,2,'热锅多倒油,大火下羊肉快速滑炒至变色盛出'),(20,3,'锅中留油下大葱炒香'),(20,4,'倒回羊肉,加孜然粉、盐翻炒均匀出锅');
INSERT INTO recipe_steps (recipe_id, step_order, content) VALUES
-- 川菜 21-30
(21,1,'豆腐切小块焯水'),(21,2,'锅中倒油,下肉末炒香,加豆瓣酱炒出红油'),(21,3,'加水和豆腐煮3分钟加花椒粉、辣椒面'),(21,4,'水淀粉勾芡,撒葱花出锅'),
(22,1,'五花肉整块冷水下锅加姜、料酒煮20分钟至断生'),(22,2,'捞出切薄片,蒜苗切段'),(22,3,'热锅少油,下肉片煸至卷曲出油'),(22,4,'加豆瓣酱、生抽、糖,下蒜苗翻炒出锅'),
(23,1,'鸡胸肉切丁,加料酒、淀粉、盐腌制'),(23,2,'黄瓜切丁,调酱汁:生抽+醋+糖+淀粉+水'),(23,3,'小火炒香花生米盛出'),(23,4,'锅中爆香干辣椒花椒蒜,下鸡丁炒变色,加黄瓜丁和酱汁翻炒,最后加花生米出锅'),
(24,1,'猪里脊切薄片,加料酒、淀粉、盐腌制'),(24,2,'豆芽和白菜叶焯水铺碗底'),(24,3,'锅中炒香豆瓣酱,加水煮开,下肉片滑熟'),(24,4,'连汤倒入碗中,撒上蒜末、干辣椒、花椒,浇热油激发香味'),
(25,1,'猪里脊切丝,加料酒、淀粉腌制'),(25,2,'木耳泡发切丝,胡萝卜、青椒切丝'),(25,3,'调鱼香汁:生抽+醋+糖+淀粉+水'),(25,4,'锅中爆香泡椒蒜末豆瓣酱,下肉丝炒至变色,加三丝翻炒,淋入鱼香汁收汁出锅'),
(26,1,'鸡腿肉切小丁加生抽、料酒腌制15分钟'),(26,2,'干辣椒剪段,姜蒜切片'),(26,3,'热锅多油,下鸡丁炸至金黄捞出'),(26,4,'锅中留底油,下干辣椒花椒姜蒜爆香,倒回鸡丁翻炒,撒芝麻出锅'),
(27,1,'牛腱子和牛肚分别煮熟,切薄片'),(27,2,'调拌汁:红油+花椒粉+生抽+醋搅匀'),(27,3,'将牛肉片、牛肚片摆盘'),(27,4,'淋上拌汁,撒花生碎和香菜'),
(28,1,'鸡腿冷水下锅加姜、料酒煮15分钟至熟'),(28,2,'捞出浸冰水5分钟使皮脆肉嫩斩块摆盘'),(28,3,'调酱汁:芝麻酱+红油+生抽+醋+花椒粉+蒜末+糖搅匀'),(28,4,'酱汁淋在鸡块上,撒花生碎、葱花和香菜'),
(29,1,'牛肉切丝,加生抽料酒腌制'),(29,2,'芹菜切段,干辣椒剪段'),(29,3,'热锅多油,下牛肉丝煸至水分蒸发'),(29,4,'加豆瓣酱、干辣椒、花椒、芹菜翻炒,生抽调味出锅'),
(30,1,'五花肉整块冷水下锅煮20分钟至熟'),(30,2,'捞出放凉切薄片,黄瓜切丝铺底'),(30,3,'将肉片整齐码放在黄瓜上'),(30,4,'调蒜泥汁:蒜末+生抽+红油+醋+糖,淋在肉片上'),
-- 粤菜 31-40
(31,1,'草鱼片加料酒、淀粉、盐腌制'),(31,2,'酸菜切段焯水,泡椒切段'),(31,3,'锅中炒香姜蒜泡椒,下酸菜翻炒,加水煮开'),(31,4,'滑入鱼片煮至变白,连汤倒入碗中,撒干辣椒花椒浇热油'),
(32,1,'鸭血切块,午餐肉切片,毛肚洗净'),(32,2,'豆芽焯水铺碗底'),(32,3,'锅中炒香豆瓣酱,加水煮开,下鸭血午餐肉毛肚煮熟'),(32,4,'倒入碗中,撒蒜末干辣椒花椒,浇热油'),
(33,1,'虾去虾线,土豆藕切片,西兰花掰小朵'),(33,2,'所有蔬菜焯水断生'),(33,3,'锅中少油炒化火锅底料,加干辣椒花椒蒜爆香'),(33,4,'下所有食材翻炒均匀出锅'),
(34,1,'鸡爪剪去指甲,冷水下锅加姜料酒焯水'),(34,2,'捞出洗净,放入泡椒和泡椒水、白醋、盐'),(34,3,'加入凉白开没过鸡爪'),(34,4,'密封冷藏腌制4小时以上即可'),
(35,1,'面条煮熟捞出,过凉水'),(35,2,'肉末下锅炒香,加芽菜炒匀'),(35,3,'调碗底:芝麻酱+红油+生抽+醋+花生碎'),(35,4,'面条放入碗中,浇上肉末芽菜和调料,撒葱花拌匀'),
(36,1,'三黄鸡处理干净,锅中水加姜葱料酒烧开'),(36,2,'提着鸡腿浸入沸水中三提三放,使鸡皮定型'),(36,3,'小火煮15分钟关火焖10分钟'),(36,4,'捞出浸冰水,斩件摆盘,蘸料:生抽+花生油+蒜末+姜末'),
(37,1,'鲈鱼处理干净,两面划斜刀,抹盐料酒腌制'),(37,2,'盘中铺姜片,放上鲈鱼,上面再放姜片葱段'),(37,3,'水开后上锅大火蒸8分钟'),(37,4,'倒掉盘中蒸出的水,撒葱丝,淋蒸鱼豉油,浇热油'),
(38,1,'基围虾洗净去虾线'),(38,2,'锅中烧水,加姜片料酒煮开'),(38,3,'下虾煮至变色弯曲(约2分钟)立即捞出'),(38,4,'摆盘,蘸料:生抽+姜末+香油'),
(39,1,'猪梅花肉切长条用叉烧酱、生抽、老抽腌制4小时'),(39,2,'烤箱预热200度烤盘垫锡纸'),(39,3,'烤20分钟后取出刷蜂蜜翻面再烤15分钟'),(39,4,'取出放凉切片'),
(40,1,'猪里脊切块,加盐、料酒、淀粉腌制'),(40,2,'菠萝切块盐水浸泡,青红椒切片'),(40,3,'肉块裹干淀粉炸至金黄,糖醋汁:番茄酱+糖+白醋+水'),(40,4,'锅中炒香糖醋汁,下肉块菠萝青红椒翻炒裹汁出锅');
INSERT INTO recipe_steps (recipe_id, step_order, content) VALUES
-- 粤菜 41-50
(41,1,'牛肉切片加生抽、料酒、淀粉腌制'),(41,2,'河粉抖散,热锅多油滑锅'),(41,3,'大火下牛肉炒至变色盛出'),(41,4,'同锅下河粉翻炒,加生抽老抽,加豆芽韭黄牛肉炒匀出锅'),
(42,1,'粉丝温水泡软,扇贝去泥沙洗净'),(42,2,'蒜切末,一半炸至金黄做成金银蒜'),(42,3,'扇贝壳上铺粉丝和扇贝,淋金银蒜和蒸鱼豉油'),(42,4,'上锅蒸6分钟出锅撒葱花淋热油'),
(43,1,'排骨斩小块加生抽、料酒、豆豉、蒜末、淀粉、糖腌制20分钟'),(43,2,'盘中平铺排骨'),(43,3,'水开后上锅大火蒸15-20分钟'),(43,4,'出锅即可'),
(44,1,'大米提前浸泡30分钟腊肠腊肉切薄片'),(44,2,'砂锅刷油,放入大米和水(1:1.2),大火煮开转小火'),(44,3,'米饭快熟时铺上腊肠腊肉盖上焖5分钟'),(44,4,'沿锅边淋少许油形成锅巴,焯好的油菜摆旁边,淋生抽即可'),
(45,1,'排骨焯水去血沫,冬瓜去皮切块'),(45,2,'锅中放排骨、姜片,加足量水'),(45,3,'大火煮开转小火炖40分钟'),(45,4,'加入冬瓜再炖10分钟加盐出锅'),
(46,1,'牛肉切片加生抽、料酒、淀粉腌制'),(46,2,'青椒切块、洋葱切片'),(46,3,'热锅多油滑炒牛肉至变色盛出'),(46,4,'锅中炒香洋葱青椒,倒回牛肉,加蚝油翻炒出锅'),
(47,1,'虾仁切粒,加猪肥膘碎、笋丁、盐搅匀做馅'),(47,2,'澄面加生粉,用滚水烫熟揉成面团'),(47,3,'面团分小剂子擀成薄皮,包入虾馅捏成饺子'),(47,4,'上锅蒸6分钟即可'),
(48,1,'粘米粉加水调成米浆'),(48,2,'平底蒸盘刷油,倒入一勺米浆晃匀'),(48,3,'打上鸡蛋、撒肉末和生菜'),(48,4,'上锅大火蒸3分钟刮起卷成肠粉淋生抽即可'),
(49,1,'面粉加酵母、糖、水揉成面团发酵1小时'),(49,2,'叉烧肉切小丁,加蚝油调味'),(49,3,'面团分小剂子擀皮,包入叉烧馅'),(49,4,'上锅蒸12分钟关火焖2分钟即可'),
(50,1,'蛋挞皮提前解冻'),(50,2,'鸡蛋打散,加淡奶油、牛奶、糖搅拌均匀过滤'),(50,3,'蛋液倒入蛋挞皮中,八分满'),(50,4,'烤箱200度烤20分钟至表面焦黄'),
-- 湘菜 51-58
(51,1,'鱼头处理干净,抹盐和料酒腌制'),(51,2,'盘中垫姜片,放上鱼头'),(51,3,'铺满剁椒水开后大火蒸12分钟'),(51,4,'倒掉盘中水,撒葱花,淋蒸鱼豉油,浇热油'),
(52,1,'五花肉切薄片,青椒切块'),(52,2,'热锅少油,下五花肉煸至卷曲出油'),(52,3,'加蒜片、豆豉炒香'),(52,4,'下青椒大火快炒,加生抽老抽调色出锅'),
(53,1,'酸豆角切小段,猪肉切末'),(53,2,'热锅倒油,下肉末炒香'),(53,3,'加干辣椒、蒜末爆香'),(53,4,'下酸豆角大火翻炒,加生抽调味出锅'),
(54,1,'腊肉腊肠腊鱼用温水洗净切片'),(54,2,'盘中依次码放腊味'),(54,3,'撒上豆豉和干辣椒,淋少许料酒'),(54,4,'水开后上锅大火蒸20分钟即可'),
(55,1,'花菜掰小朵焯水半分钟'),(55,2,'五花肉切薄片'),(55,3,'热锅少油下五花肉煸出油,加蒜干辣椒豆瓣酱炒香'),(55,4,'下花菜大火翻炒,加生抽调味出锅'),
(56,1,'小龙虾刷洗干净去虾线'),(56,2,'热锅多油,下小龙虾炸至变红捞出'),(56,3,'锅中留油,下姜蒜豆瓣酱干辣椒花椒炒香'),(56,4,'倒回小龙虾加啤酒焖煮8分钟大火收汁撒紫苏出锅'),
(57,1,'青椒洗净去蒂,直接在干锅上烙至表皮焦黑'),(57,2,'趁热剥去焦皮,撕成条'),(57,3,'皮蛋切瓣摆盘'),(57,4,'将辣椒条放入,加蒜末、生抽、醋、香油,用擂钵擂拌均匀'),
(58,1,'酸菜切碎焯水挤干'),(58,2,'热锅倒油下肉末炒香'),(58,3,'加干辣椒蒜末爆香'),(58,4,'下酸菜大火翻炒,加生抽调味出锅'),
-- 东北菜 59-66
(59,1,'猪里脊切厚片,加盐、料酒腌制'),(59,2,'淀粉+水调成糊,肉片裹糊'),(59,3,'油温六成热逐片下锅炸至定型捞出,油温升高复炸至金黄酥脆'),(59,4,'另起锅熬糖醋汁:白醋+糖煮至粘稠,加胡萝卜丝葱丝,下肉片快速翻炒裹汁出锅'),
(60,1,'茄子土豆青椒切滚刀块'),(60,2,'锅中多油,分别炸土豆和茄子至金黄'),(60,3,'调碗汁:生抽+老抽+糖+盐+水+淀粉'),(60,4,'锅中留油爆香蒜末,下所有食材翻炒,倒入碗汁收汁出锅');
INSERT INTO recipe_steps (recipe_id, step_order, content) VALUES
-- 东北菜继续 + 早餐
(61,1,'五花肉切块焯水,粉条泡软'),(61,2,'锅中少许油下五花肉煸至微黄'),(61,3,'加生抽、老抽、八角、姜片,加水没过肉'),(61,4,'炖30分钟后加粉条和白菜再炖10分钟收汁出锅'),
(62,1,'排骨焯水,土豆茄子切块,豆角掰段,玉米切段'),(62,2,'锅中炒香排骨,加生抽老抽上色'),(62,3,'加水没过排骨先炖20分钟'),(62,4,'加入所有蔬菜再炖15分钟加盐调味出锅'),
(63,1,'猪里脊切丝,加料酒、淀粉、蛋清腌制'),(63,2,'大葱白切丝摆盘,甜面酱+生抽+糖+水调酱汁'),(63,3,'锅中滑炒肉丝至变色盛出'),(63,4,'锅中炒香酱汁,倒回肉丝翻炒裹酱,盛入葱丝盘中,配豆腐皮卷食'),
(64,1,'红薯去皮切滚刀块'),(64,2,'油温六成热,下红薯块炸至金黄熟透捞出'),(64,3,'另起锅加白糖和少量水,小火熬至焦黄色'),(64,4,'快速下入炸好的红薯翻滚裹糖,趁热装盘(配一碗凉水拔丝)'),
(65,1,'五花肉冷水下锅煮20分钟捞出切薄片'),(65,2,'酸菜切丝洗两遍挤干'),(65,3,'锅中放肉片和姜片八角加水炖20分钟'),(65,4,'加入酸菜和粉条再炖10分钟加盐出锅'),
(66,1,'猪瘦肉切块,加盐料酒腌制,裹淀粉糊'),(66,2,'油温六成热下锅炸至金黄捞出'),(66,3,'调酱汁:生抽+醋+糖+水+淀粉'),(66,4,'锅中留底油,下青椒胡萝卜翻炒,倒回肉段,淋酱汁翻炒均匀出锅'),
-- 67-72
(67,1,'面粉加水揉成软面团醒30分钟'),(67,2,'擀成薄饼,刷油叠层'),(67,3,'平底锅少油,放饼,待鼓起时戳洞灌入蛋液'),(67,4,'两面煎至金黄,刷甜面酱包入生菜即可'),
(68,1,'大米提前浸泡30分钟'),(68,2,'皮蛋切丁,瘦肉切丝加姜腌制'),(68,3,'锅中水开下大米中小火煮25分钟至粥粘稠'),(68,4,'加入皮蛋和肉丝再煮5分钟加盐调味出锅'),
(69,1,'面粉加水调成面糊,打入鸡蛋搅匀'),(69,2,'加入葱花、盐搅拌均匀'),(69,3,'平底锅刷油,倒入一勺面糊摊平'),(69,4,'小火两面煎至金黄即可'),
(70,1,'小米洗净,南瓜去皮切小块'),(70,2,'锅中加水和小米,大火煮开转小火'),(70,3,'煮15分钟后加入南瓜'),(70,4,'再煮10分钟至南瓜软烂小米粘稠即可'),
(71,1,'猪肉馅加白菜碎、生抽、料酒、盐拌匀'),(71,2,'饺子皮包入馅料'),(71,3,'平底锅倒油摆入饺子,小火煎到底部金黄'),(71,4,'加半碗水盖盖焖5分钟至水收干即可'),
(72,1,'鸡蛋煎熟,火腿片略煎'),(72,2,'面包片烤至微黄'),(72,3,'面包片上放生菜、煎蛋、火腿片'),(72,4,'挤上沙拉酱,盖上另一片面包对切即可'),
-- 73-78
(73,1,'黄豆提前泡8小时打成豆浆过滤煮沸'),(73,2,'面粉+酵母+泡打粉+水揉成面团醒2小时'),(73,3,'面团擀长条切段,两段叠起用筷子压中线'),(73,4,'油温180度下锅炸至金黄膨胀捞出'),
(74,1,'猪肉馅加生抽、盐、料酒、葱花拌匀'),(74,2,'馄饨皮包入馅料捏紧'),(74,3,'锅中水开下馄饨煮至浮起再煮1分钟'),(74,4,'碗中放紫菜、虾皮、盐、葱花和开水做汤底,盛入馄饨'),
(75,1,'面粉+酵母+水揉成面团醒发1小时'),(75,2,'五花肉加生抽老抽八角桂皮姜炖40分钟至软烂切碎'),(75,3,'面团分小剂子擀成饼,平底锅烙至两面金黄'),(75,4,'饼从中间划开夹入肉碎,浇一勺肉汤'),
(76,1,'糯米提前泡4小时荷叶泡软'),(76,2,'鸡腿肉切块加生抽蚝油腌制'),(76,3,'香菇腊肠切片,与鸡肉和糯米拌匀'),(76,4,'荷叶包入糯米鸡上锅蒸40分钟'),
(77,1,'面粉和绿豆面加水调成稀面糊'),(77,2,'平底铛刷油,倒一勺面糊摊成薄圆'),(77,3,'打上鸡蛋摊开,翻面'),(77,4,'刷甜面酱和辣酱,放薄脆,撒葱花卷起'),
(78,1,'红豆煮烂加糖压成豆沙'),(78,2,'面粉加酵母水揉成面团醒发1小时'),(78,3,'面团分小剂子擀皮包入豆沙'),(78,4,'上锅蒸15分钟关火焖3分钟');
INSERT INTO recipe_steps (recipe_id, step_order, content) VALUES
-- 汤羹 79-86 + 凉菜 87-94 + 主食 95-100
(79,1,'西红柿切块,鸡蛋打散'),(79,2,'锅中倒油下西红柿炒出汁'),(79,3,'加水煮开'),(79,4,'淋入蛋液搅散,加盐调味,撒葱花淋香油'),
(80,1,'紫菜撕碎放碗中'),(80,2,'锅中水烧开'),(80,3,'淋入蛋液形成蛋花'),(80,4,'倒入碗中,加盐、虾皮、香油'),
(81,1,'排骨焯水备用'),(81,2,'锅中放入排骨、姜片加足水'),(81,3,'大火煮开转小火炖40分钟'),(81,4,'加入玉米段再炖15分钟加盐出锅'),
(82,1,'牛肉末加蛋清淀粉拌匀'),(82,2,'锅中加水烧开,下豆腐丁'),(82,3,'滑入牛肉末搅散煮2分钟'),(82,4,'加盐白胡椒调味,淀粉勾薄芡,撒香菜出锅'),
(83,1,'木耳泡发切丝,豆腐切丝'),(83,2,'锅中水开下豆腐丝木耳丝煮2分钟'),(83,3,'加生抽、盐、白胡椒粉'),(83,4,'淋入蛋液和淀粉水,加醋和香油出锅'),
(84,1,'鲫鱼处理干净,两面划刀'),(84,2,'热锅倒油煎鱼至两面金黄'),(84,3,'加开水没过鱼,加姜葱料酒'),(84,4,'大火煮10分钟汤变奶白加豆腐块再煮5分钟加盐调味'),
(85,1,'排骨焯水,莲藕去皮切厚块'),(85,2,'排骨、莲藕、姜片、红枣一起入砂锅'),(85,3,'加水大火煮开转小火炖1小时'),(85,4,'加盐调味出锅'),
(86,1,'银耳提前泡发撕小朵,莲子泡发去芯'),(86,2,'银耳、莲子、红枣入锅加水'),(86,3,'大火煮开转小火炖30分钟'),(86,4,'加冰糖再炖10分钟至银耳出胶'),
(87,1,'黄瓜洗净拍碎切段'),(87,2,'蒜切末'),(87,3,'调拌汁:蒜末+生抽+醋+盐+辣椒油+香油'),(87,4,'将拌汁倒入黄瓜中拌匀即可'),
(88,1,'内酯豆腐倒扣入盘中'),(88,2,'皮蛋切丁放在豆腐上'),(88,3,'葱切末撒上'),(88,4,'淋生抽、醋、香油、盐调成的汁'),
(89,1,'木耳泡发后焯水1分钟'),(89,2,'捞出过凉水沥干'),(89,3,'大蒜切末'),(89,4,'加蒜末、生抽、醋、盐、辣椒油、香油拌匀'),
(90,1,'粉丝泡软焯水,黄瓜胡萝卜切丝'),(90,2,'粉丝沥干和蔬菜丝混合'),(90,3,'蒜切末'),(90,4,'加蒜末、生抽、醋、盐、辣椒油、香油拌匀'),
(91,1,'番茄洗净切片'),(91,2,'番茄片摆盘'),(91,3,'均匀撒上白糖'),(91,4,'冷藏10分钟更佳'),
(92,1,'鸡胸肉冷水下锅煮熟,撕成细丝'),(92,2,'黄瓜切丝'),(92,3,'调酱汁:芝麻酱+生抽+醋+蒜末+辣椒油+盐'),(92,4,'鸡丝黄瓜放入碗中,淋酱汁拌匀'),
(93,1,'黄瓜洗净用刀面拍裂切段'),(93,2,'蒜切末'),(93,3,'加蒜末、生抽、醋、盐、辣椒油、香油'),(93,4,'拌匀即可'),
(94,1,'海带丝洗净焯水2分钟'),(94,2,'捞出过凉水沥干'),(94,3,'蒜切末'),(94,4,'加蒜末、生抽、醋、盐、辣椒油、香油拌匀'),
(95,1,'鸡蛋打散加少许盐,葱切粒'),(95,2,'热锅多油,倒入蛋液快速搅散'),(95,3,'加入米饭大火翻炒压散'),(95,4,'加盐调味,撒大量葱花翻炒出锅'),
(96,1,'番茄切块,鸡蛋打散'),(96,2,'锅中少油炒香番茄出汁,加水煮开'),(96,3,'下入面条煮至八分熟'),(96,4,'淋入蛋液成蛋花,加盐调味,撒葱花出锅'),
(97,1,'肉末炒香,加甜面酱和黄豆酱小火炸出酱香'),(97,2,'面条煮熟捞出过凉水'),(97,3,'黄瓜切丝'),(97,4,'面条盛碗,码上肉酱和黄瓜丝,撒葱花拌匀'),
(98,1,'葱切段,锅中多油小火炸葱至焦黄出香'),(98,2,'葱油过滤备用'),(98,3,'调碗底:生抽+老抽+糖混合'),(98,4,'面条煮熟捞出,浇葱油和酱油汁拌匀'),
(99,1,'米粉提前泡软'),(99,2,'鸡蛋炒散,豆芽焯水,火腿切片'),(99,3,'热锅多油下米粉大火快炒'),(99,4,'加入鸡蛋豆芽火腿,生抽调味翻炒出锅'),
(100,1,'面条放入碗中'),(100,2,'加酱油、猪油、盐、葱花'),(100,3,'开水冲入碗中搅匀'),(100,4,'煮好的面条捞入碗中即可');

View File

@@ -0,0 +1,59 @@
-- ChowBox 数据库表结构
-- MySQL 5.7+
CREATE DATABASE IF NOT EXISTS chowbox DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE chowbox;
-- 菜谱表
CREATE TABLE IF NOT EXISTS recipes (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL COMMENT '菜名',
difficulty TINYINT NOT NULL DEFAULT 2 COMMENT '难度 1-5 星',
cook_time INT NOT NULL COMMENT '烹饪时长(分钟)',
image_url VARCHAR(255) DEFAULT '' COMMENT '成品图URL',
category VARCHAR(50) NOT NULL COMMENT '菜系分类(川菜/粤菜/家常菜等)',
season VARCHAR(20) DEFAULT 'all' COMMENT '适宜季节(spring/summer/autumn/winter/all)',
meal_time VARCHAR(20) DEFAULT 'all' COMMENT '餐时(breakfast/lunch/dinner/all)',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='菜谱';
-- 菜谱食材表
CREATE TABLE IF NOT EXISTS recipe_ingredients (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
recipe_id BIGINT NOT NULL COMMENT '菜谱ID',
ingredient_name VARCHAR(50) NOT NULL COMMENT '食材名称',
amount VARCHAR(50) DEFAULT '' COMMENT '用量(如2个/200克)',
is_staple TINYINT DEFAULT 1 COMMENT '是否主料(1主料/0辅料)',
FOREIGN KEY (recipe_id) REFERENCES recipes(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='菜谱食材';
-- 菜谱步骤表
CREATE TABLE IF NOT EXISTS recipe_steps (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
recipe_id BIGINT NOT NULL COMMENT '菜谱ID',
step_order INT NOT NULL COMMENT '步骤序号',
content VARCHAR(500) NOT NULL COMMENT '步骤描述',
image_url VARCHAR(255) DEFAULT '' COMMENT '步骤图URL',
FOREIGN KEY (recipe_id) REFERENCES recipes(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='菜谱步骤';
-- 用户偏好表
CREATE TABLE IF NOT EXISTS user_preferences (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
openid VARCHAR(64) NOT NULL UNIQUE COMMENT '微信openid',
taste VARCHAR(50) DEFAULT '' COMMENT '口味偏好(辣/清淡/酸甜等)',
allergies VARCHAR(200) DEFAULT '' COMMENT '过敏/忌口(逗号分隔)',
price_range VARCHAR(20) DEFAULT 'all' COMMENT '外卖价格区间(low/medium/high/all)',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户偏好';
-- 开盒记录表
CREATE TABLE IF NOT EXISTS box_history (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
openid VARCHAR(64) NOT NULL COMMENT '微信openid',
box_type VARCHAR(20) NOT NULL COMMENT '盲盒类型(takeout/fridge/explore)',
result_data JSON COMMENT '结果数据',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_openid_time (openid, created_at DESC)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='开盒记录';