153 lines
4.0 KiB
JavaScript
153 lines
4.0 KiB
JavaScript
const { request } = require('../../utils/request')
|
|
|
|
const emptyForm = {
|
|
name: '',
|
|
category: '轻食',
|
|
description: '',
|
|
calories: '',
|
|
protein: '',
|
|
fat: '',
|
|
carbs: '',
|
|
fiber: '',
|
|
tagsText: ''
|
|
}
|
|
|
|
Page({
|
|
data: {
|
|
keyword: '',
|
|
recipes: [],
|
|
loading: false,
|
|
editId: null,
|
|
form: { ...emptyForm },
|
|
importText: '[{"name":"低脂鸡肉饭","category":"减脂轻食","calories":360,"protein":30,"fat":10,"carbs":34,"fiber":5,"tags":["减脂"]}]'
|
|
},
|
|
|
|
onShow() {
|
|
this.fetchRecipes()
|
|
},
|
|
|
|
onInput(e) {
|
|
const field = e.currentTarget.dataset.field
|
|
this.setData({ [field]: e.detail.value })
|
|
},
|
|
|
|
onFormInput(e) {
|
|
const field = e.currentTarget.dataset.field
|
|
this.setData({ [`form.${field}`]: e.detail.value })
|
|
},
|
|
|
|
async fetchRecipes() {
|
|
this.setData({ loading: true })
|
|
try {
|
|
const data = await request({ url: `/recipes?keyword=${encodeURIComponent(this.data.keyword)}&page=1&page_size=100` })
|
|
const recipes = (data.items || []).map((item) => ({
|
|
...item,
|
|
tags_text: (item.tags || []).join('、')
|
|
}))
|
|
this.setData({ recipes })
|
|
} catch (err) {
|
|
// handled
|
|
} finally {
|
|
this.setData({ loading: false })
|
|
}
|
|
},
|
|
|
|
startCreate() {
|
|
this.setData({ editId: null, form: { ...emptyForm } })
|
|
},
|
|
|
|
startEdit(e) {
|
|
const id = Number(e.currentTarget.dataset.id)
|
|
const row = this.data.recipes.find((item) => item.id === id)
|
|
if (!row) return
|
|
this.setData({
|
|
editId: row.id,
|
|
form: {
|
|
name: row.name || '',
|
|
category: row.category || '轻食',
|
|
description: row.description || '',
|
|
calories: String(row.calories || ''),
|
|
protein: String(row.protein || ''),
|
|
fat: String(row.fat || ''),
|
|
carbs: String(row.carbs || ''),
|
|
fiber: String(row.fiber || ''),
|
|
tagsText: (row.tags || []).join(',')
|
|
}
|
|
})
|
|
},
|
|
|
|
buildRecipePayload() {
|
|
const f = this.data.form
|
|
return {
|
|
name: f.name,
|
|
category: f.category,
|
|
description: f.description,
|
|
calories: Number(f.calories),
|
|
protein: Number(f.protein),
|
|
fat: Number(f.fat),
|
|
carbs: Number(f.carbs),
|
|
fiber: Number(f.fiber),
|
|
tags: (f.tagsText || '').split(',').map(i => i.trim()).filter(Boolean)
|
|
}
|
|
},
|
|
|
|
async saveRecipe() {
|
|
const payload = this.buildRecipePayload()
|
|
if (!payload.name) {
|
|
wx.showToast({ title: '请填写食谱名称', icon: 'none' })
|
|
return
|
|
}
|
|
try {
|
|
if (this.data.editId) {
|
|
await request({ url: `/recipes/${this.data.editId}`, method: 'PUT', data: payload })
|
|
wx.showToast({ title: '食谱已更新', icon: 'success' })
|
|
} else {
|
|
await request({ url: '/recipes', method: 'POST', data: payload })
|
|
wx.showToast({ title: '食谱已创建', icon: 'success' })
|
|
}
|
|
this.fetchRecipes()
|
|
} catch (err) {
|
|
// handled
|
|
}
|
|
},
|
|
|
|
async deleteRecipe(e) {
|
|
const id = e.currentTarget.dataset.id
|
|
wx.showModal({
|
|
title: '删除食谱',
|
|
content: `确定删除食谱 ID ${id} 吗?`,
|
|
success: async (res) => {
|
|
if (!res.confirm) return
|
|
try {
|
|
await request({ url: `/recipes/${id}`, method: 'DELETE' })
|
|
wx.showToast({ title: '删除成功', icon: 'success' })
|
|
this.fetchRecipes()
|
|
} catch (err) {
|
|
// handled
|
|
}
|
|
}
|
|
})
|
|
},
|
|
|
|
async importDefaultSeed() {
|
|
try {
|
|
await request({ url: '/recipes/import', method: 'POST', data: {} })
|
|
wx.showToast({ title: '默认食谱导入成功', icon: 'success' })
|
|
this.fetchRecipes()
|
|
} catch (err) {
|
|
// handled
|
|
}
|
|
},
|
|
|
|
async importByJSON() {
|
|
try {
|
|
const items = JSON.parse(this.data.importText)
|
|
await request({ url: '/recipes/import', method: 'POST', data: { items } })
|
|
wx.showToast({ title: '批量导入成功', icon: 'success' })
|
|
this.fetchRecipes()
|
|
} catch (err) {
|
|
wx.showToast({ title: '导入 JSON 格式错误', icon: 'none' })
|
|
}
|
|
}
|
|
})
|