1
0
mirror of synced 2025-11-06 04:20:50 +08:00
Files
cook/scripts/convert.ts
Reina b13924da4f feat: Implement warnings for incompatible food combinations (#82)
* feat: 添加食物相克检测功能及相关数据支持

* chore: 修改 .gitignore 设置,并删除 recipe.json 的 git 引用

* style: 格式化 incompatible-foods.ts 文件中的代码,修改缩紧为 2

* fix: 修复导入语句,确保正确使用 Vue 的 ref 和 computed

* refactor: 优化相克检测逻辑,使用 Set 提高性能

* refactor: 移除不必要的 IncompatibleRule 类型定义

* fix: 添加缺失字段检查,确保不完整数据不会被处理

* style: 使用 eslint 优化代码格式
2025-09-26 18:36:38 +08:00

113 lines
2.9 KiB
TypeScript

import type { IncompatibleRule, RecipeItem, Recipes } from '../app/types'
// convert csv to json
import fs from 'node:fs'
import consola from 'consola'
import { config } from './config'
function run() {
const csvData = fs.readFileSync(config.recipeCsvFile, 'utf-8')
const lines = csvData.split(/\r?\n/)
const headers = 'name,stuff,bv,difficulty,tags,methods,tools,'
if (lines.length < 2) {
throw new Error('No data in csv file')
}
if (lines[0]?.trim() !== headers) {
consola.warn(`Headers Changed: ${lines[0]}`)
return
}
const recipeJson: Recipes = []
const sep = '、'
lines.slice(1).forEach((line) => {
if (line) {
const attrs = line.split(',')
if (attrs.length < 7) {
consola.warn(`Invalid line: ${line}`)
return
}
const stuff = attrs[1]?.trim().split(sep) || []
recipeJson.push({
name: attrs[0]?.trim() || '',
stuff,
// link: attrs[2].trim(),
// bv id
bv: attrs[2]?.trim().replace('https://www.bilibili.com/video/', ''),
difficulty: attrs[3] && attrs[3].trim() as RecipeItem['difficulty'],
tags: attrs[4] ? attrs[4].trim().split(sep) : [],
methods: attrs[5] ? (attrs[5].trim().split(sep)) as RecipeItem['methods'] : [],
tools: attrs[6] ? attrs[6].trim().split(sep) : [],
})
}
})
fs.writeFileSync(config.recipeJsonFile, JSON.stringify(recipeJson))
consola.success(`Generate file: ${config.recipeJsonFile}`)
}
/**
* 转换食物相克数据
*/
function convertIncompatibleFoods() {
consola.info('---')
consola.info('Convert Incompatible Foods Data...')
try {
const csvData = fs.readFileSync(config.incompatibleFoodsCsvFile, 'utf-8')
const lines = csvData.split(/\r?\n/)
const headers = 'foodA,foodB,reason'
if (lines.length < 2) {
throw new Error('No data in incompatible foods csv file')
}
if (lines[0]?.trim() !== headers) {
consola.warn(`Headers Changed: ${lines[0]}`)
return
}
const incompatibleRules: IncompatibleRule[] = []
lines.slice(1).forEach((line) => {
if (line.trim()) {
const attrs = line.split(',')
if (attrs.length < 3) {
consola.warn(`Invalid line: ${line}`)
return
}
const foodA = attrs[0]?.trim()
const foodB = attrs[1]?.trim()
const reason = attrs[2]?.trim()
if (!foodA || !foodB || !reason) {
consola.warn(`Missing required field(s) in line: ${line}`)
return
}
incompatibleRules.push({
foodA,
foodB,
reason,
})
}
})
fs.writeFileSync(config.incompatibleFoodsJsonFile, JSON.stringify(incompatibleRules, null, 2))
consola.success(`Generate file: ${config.incompatibleFoodsJsonFile}`)
}
catch (error) {
consola.error('Failed to convert incompatible foods data:', error)
}
}
function main() {
run()
convertIncompatibleFoods()
}
main()