首页 / 应用软件 / 实战教程,在网站中添加在线食谱管理与食材采购清单工具

实战教程,在网站中添加在线食谱管理与食材采购清单工具

实战教程:在WordPress网站中添加在线食谱管理与食材采购清单工具

引言:为什么网站需要实用小工具?

在当今互联网时代,网站的功能性已成为吸引和留住用户的关键因素。对于美食、生活类网站而言,提供实用工具不仅能增加用户粘性,还能显著提升用户体验。想象一下,当用户在你的美食博客上找到心仪的食谱后,能够直接保存到个人收藏夹,并一键生成食材采购清单,这将大大简化他们的烹饪准备过程。

本教程将详细指导您如何通过WordPress代码二次开发,为您的网站添加在线食谱管理与食材采购清单工具。我们将从零开始,逐步构建这两个实用功能,无需依赖昂贵的插件,完全自主控制功能与样式。

第一部分:准备工作与环境搭建

1.1 开发环境要求

在开始之前,请确保您的开发环境满足以下要求:

  • WordPress 5.0或更高版本
  • PHP 7.2或更高版本(建议7.4+)
  • MySQL 5.6或更高版本
  • 基本的HTML、CSS、JavaScript和PHP知识
  • 代码编辑器(如VS Code、Sublime Text等)
  • 本地开发环境(如XAMPP、MAMP或Local by Flywheel)

1.2 创建子主题

为了避免主题更新时丢失自定义代码,我们首先创建一个子主题:

  1. 在WordPress的wp-content/themes/目录下创建新文件夹,命名为my-cooking-tools
  2. 在该文件夹中创建style.css文件,添加以下内容:
/*
Theme Name: My Cooking Tools
Theme URI: https://yourwebsite.com
Description: 子主题用于添加食谱管理功能
Author: Your Name
Author URI: https://yourwebsite.com
Template: your-parent-theme  // 替换为您的父主题名称
Version: 1.0.0
*/

/* 导入父主题样式 */
@import url("../your-parent-theme/style.css");
  1. 创建functions.php文件,添加以下基础代码:
<?php
// 子主题功能文件

// 添加父主题样式
add_action('wp_enqueue_scripts', 'my_cooking_tools_enqueue_styles');
function my_cooking_tools_enqueue_styles() {
    wp_enqueue_style('parent-style', get_template_directory_uri() . '/style.css');
    wp_enqueue_style('child-style', get_stylesheet_directory_uri() . '/style.css', array('parent-style'));
}

// 在这里添加自定义功能代码
?>
  1. 在WordPress后台启用这个子主题

第二部分:数据库设计与数据模型

2.1 创建自定义数据库表

我们需要创建两个自定义表来存储食谱和食材清单数据。在子主题的functions.php文件中添加以下代码:

// 创建自定义数据库表
register_activation_hook(__FILE__, 'cooking_tools_create_tables');
function cooking_tools_create_tables() {
    global $wpdb;
    
    $charset_collate = $wpdb->get_charset_collate();
    $recipes_table = $wpdb->prefix . 'user_recipes';
    $ingredients_table = $wpdb->prefix . 'recipe_ingredients';
    $shopping_lists_table = $wpdb->prefix . 'shopping_lists';
    
    // 用户食谱表
    $recipes_sql = "CREATE TABLE IF NOT EXISTS $recipes_table (
        id mediumint(9) NOT NULL AUTO_INCREMENT,
        user_id bigint(20) NOT NULL,
        recipe_title varchar(255) NOT NULL,
        recipe_content longtext NOT NULL,
        prep_time int(11),
        cook_time int(11),
        servings int(11),
        difficulty varchar(50),
        category varchar(100),
        tags text,
        featured_image varchar(255),
        created_at datetime DEFAULT CURRENT_TIMESTAMP,
        updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        PRIMARY KEY (id),
        KEY user_id (user_id)
    ) $charset_collate;";
    
    // 食谱食材表
    $ingredients_sql = "CREATE TABLE IF NOT EXISTS $ingredients_table (
        id mediumint(9) NOT NULL AUTO_INCREMENT,
        recipe_id mediumint(9) NOT NULL,
        ingredient_name varchar(255) NOT NULL,
        quantity decimal(10,2),
        unit varchar(50),
        notes text,
        sort_order int(11) DEFAULT 0,
        PRIMARY KEY (id),
        KEY recipe_id (recipe_id)
    ) $charset_collate;";
    
    // 采购清单表
    $shopping_lists_sql = "CREATE TABLE IF NOT EXISTS $shopping_lists_table (
        id mediumint(9) NOT NULL AUTO_INCREMENT,
        user_id bigint(20) NOT NULL,
        list_name varchar(255) NOT NULL,
        ingredients text NOT NULL,
        status varchar(50) DEFAULT 'active',
        created_at datetime DEFAULT CURRENT_TIMESTAMP,
        updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        PRIMARY KEY (id),
        KEY user_id (user_id)
    ) $charset_collate;";
    
    require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
    dbDelta($recipes_sql);
    dbDelta($ingredients_sql);
    dbDelta($shopping_lists_sql);
}

2.2 数据模型类

为了更好的代码组织,我们创建一个数据模型类来处理数据库操作:

// 食谱管理数据模型类
class CookingTools_Model {
    private $wpdb;
    private $recipes_table;
    private $ingredients_table;
    private $shopping_lists_table;
    
    public function __construct() {
        global $wpdb;
        $this->wpdb = $wpdb;
        $this->recipes_table = $wpdb->prefix . 'user_recipes';
        $this->ingredients_table = $wpdb->prefix . 'recipe_ingredients';
        $this->shopping_lists_table = $wpdb->prefix . 'shopping_lists';
    }
    
    // 获取用户食谱
    public function get_user_recipes($user_id, $limit = 20, $offset = 0) {
        $sql = $this->wpdb->prepare(
            "SELECT * FROM {$this->recipes_table} WHERE user_id = %d ORDER BY created_at DESC LIMIT %d OFFSET %d",
            $user_id, $limit, $offset
        );
        return $this->wpdb->get_results($sql);
    }
    
    // 获取单个食谱
    public function get_recipe($recipe_id, $user_id = null) {
        if ($user_id) {
            $sql = $this->wpdb->prepare(
                "SELECT * FROM {$this->recipes_table} WHERE id = %d AND user_id = %d",
                $recipe_id, $user_id
            );
        } else {
            $sql = $this->wpdb->prepare(
                "SELECT * FROM {$this->recipes_table} WHERE id = %d",
                $recipe_id
            );
        }
        return $this->wpdb->get_row($sql);
    }
    
    // 保存食谱
    public function save_recipe($data) {
        $defaults = array(
            'user_id' => get_current_user_id(),
            'created_at' => current_time('mysql'),
            'updated_at' => current_time('mysql')
        );
        
        $data = wp_parse_args($data, $defaults);
        
        if (isset($data['id']) && $data['id'] > 0) {
            // 更新现有食谱
            $recipe_id = $data['id'];
            unset($data['id']);
            $this->wpdb->update($this->recipes_table, $data, array('id' => $recipe_id));
            return $recipe_id;
        } else {
            // 插入新食谱
            unset($data['id']);
            $this->wpdb->insert($this->recipes_table, $data);
            return $this->wpdb->insert_id;
        }
    }
    
    // 获取食谱食材
    public function get_recipe_ingredients($recipe_id) {
        $sql = $this->wpdb->prepare(
            "SELECT * FROM {$this->ingredients_table} WHERE recipe_id = %d ORDER BY sort_order ASC",
            $recipe_id
        );
        return $this->wpdb->get_results($sql);
    }
    
    // 保存食谱食材
    public function save_recipe_ingredients($recipe_id, $ingredients) {
        // 先删除旧的食材
        $this->wpdb->delete($this->ingredients_table, array('recipe_id' => $recipe_id));
        
        // 插入新食材
        foreach ($ingredients as $index => $ingredient) {
            $ingredient_data = array(
                'recipe_id' => $recipe_id,
                'ingredient_name' => sanitize_text_field($ingredient['name']),
                'quantity' => floatval($ingredient['quantity']),
                'unit' => sanitize_text_field($ingredient['unit']),
                'notes' => sanitize_text_field($ingredient['notes']),
                'sort_order' => $index
            );
            $this->wpdb->insert($this->ingredients_table, $ingredient_data);
        }
    }
    
    // 获取用户采购清单
    public function get_user_shopping_lists($user_id) {
        $sql = $this->wpdb->prepare(
            "SELECT * FROM {$this->shopping_lists_table} WHERE user_id = %d ORDER BY created_at DESC",
            $user_id
        );
        return $this->wpdb->get_results($sql);
    }
    
    // 保存采购清单
    public function save_shopping_list($data) {
        $defaults = array(
            'user_id' => get_current_user_id(),
            'status' => 'active',
            'created_at' => current_time('mysql'),
            'updated_at' => current_time('mysql')
        );
        
        $data = wp_parse_args($data, $defaults);
        
        if (isset($data['id']) && $data['id'] > 0) {
            // 更新现有清单
            $list_id = $data['id'];
            unset($data['id']);
            $this->wpdb->update($this->shopping_lists_table, $data, array('id' => $list_id));
            return $list_id;
        } else {
            // 插入新清单
            unset($data['id']);
            $this->wpdb->insert($this->shopping_lists_table, $data);
            return $this->wpdb->insert_id;
        }
    }
    
    // 删除食谱
    public function delete_recipe($recipe_id, $user_id) {
        // 先删除相关食材
        $this->wpdb->delete($this->ingredients_table, array('recipe_id' => $recipe_id));
        
        // 再删除食谱
        return $this->wpdb->delete($this->recipes_table, 
            array('id' => $recipe_id, 'user_id' => $user_id)
        );
    }
}

第三部分:前端界面设计与开发

3.1 创建食谱管理页面模板

在子主题目录中创建recipe-manager.php文件:

<?php
/**
 * Template Name: 食谱管理器
 */
get_header(); ?>

<div class="cooking-tools-container">
    <div class="recipe-manager-wrapper">
        <header class="recipe-manager-header">
            <h1><?php the_title(); ?></h1>
            <div class="user-actions">
                <?php if (is_user_logged_in()): ?>
                    <button id="add-new-recipe" class="btn btn-primary">添加新食谱</button>
                    <a href="#shopping-lists" class="btn btn-secondary">我的采购清单</a>
                <?php else: ?>
                    <p>请<a href="<?php echo wp_login_url(get_permalink()); ?>">登录</a>以使用食谱管理功能</p>
                <?php endif; ?>
            </div>
        </header>
        
        <?php if (is_user_logged_in()): ?>
        <div class="recipe-manager-content">
            <!-- 食谱列表区域 -->
            <section id="recipes-list" class="recipes-section">
                <h2>我的食谱</h2>
                <div class="recipes-filter">
                    <input type="text" id="recipe-search" placeholder="搜索食谱..." class="search-input">
                    <select id="category-filter" class="filter-select">
                        <option value="">所有分类</option>
                        <option value="早餐">早餐</option>
                        <option value="午餐">午餐</option>
                        <option value="晚餐">晚餐</option>
                        <option value="甜点">甜点</option>
                        <option value="饮品">饮品</option>
                    </select>
                </div>
                <div class="recipes-grid" id="recipes-container">
                    <!-- 食谱将通过AJAX加载 -->
                    <div class="loading-spinner">加载中...</div>
                </div>
                <div class="pagination" id="recipes-pagination"></div>
            </section>
            
            <!-- 食谱编辑/添加区域 -->
            <section id="recipe-editor" class="editor-section" style="display:none;">
                <h2 id="editor-title">添加新食谱</h2>
                <form id="recipe-form" class="recipe-form">
                    <input type="hidden" id="recipe-id" name="recipe_id" value="0">
                    
                    <div class="form-group">
                        <label for="recipe-title">食谱名称 *</label>
                        <input type="text" id="recipe-title" name="recipe_title" required class="form-control">
                    </div>
                    
                    <div class="form-row">
                        <div class="form-group">
                            <label for="prep-time">准备时间 (分钟)</label>
                            <input type="number" id="prep-time" name="prep_time" min="0" class="form-control">
                        </div>
                        <div class="form-group">
                            <label for="cook-time">烹饪时间 (分钟)</label>
                            <input type="number" id="cook-time" name="cook_time" min="0" class="form-control">
                        </div>
                        <div class="form-group">
                            <label for="servings">份量</label>
                            <input type="number" id="servings" name="servings" min="1" class="form-control">
                        </div>
                    </div>
                    
                    <div class="form-group">
                        <label for="difficulty">难度</label>
                        <select id="difficulty" name="difficulty" class="form-control">
                            <option value="">选择难度</option>
                            <option value="简单">简单</option>
                            <option value="中等">中等</option>
                            <option value="困难">困难</option>
                        </select>
                    </div>
                    
                    <div class="form-group">
                        <label for="category">分类</label>
                        <select id="category" name="category" class="form-control">
                            <option value="">选择分类</option>
                            <option value="早餐">早餐</option>
                            <option value="午餐">午餐</option>
                            <option value="晚餐">晚餐</option>
                            <option value="甜点">甜点</option>
                            <option value="饮品">饮品</option>
                            <option value="其他">其他</option>
                        </select>
                    </div>
                    
                    <div class="form-group">
                        <label for="recipe-content">食谱步骤 *</label>
                        <textarea id="recipe-content" name="recipe_content" rows="8" required class="form-control"></textarea>
                        <small class="form-text">请详细描述烹饪步骤,每一步用换行分隔</small>
                    </div>
                    
                    <!-- 食材管理部分 -->
                    <div class="form-group">
                        <label>食材清单</label>
                        <div class="ingredients-container" id="ingredients-container">
                            <div class="ingredient-row">
                                <input type="text" class="ingredient-name" placeholder="食材名称" name="ingredients[0][name]">
                                <input type="number" step="0.01" class="ingredient-quantity" placeholder="数量" name="ingredients[0][quantity]">
                                <input type="text" class="ingredient-unit" placeholder="单位 (克/个/汤匙等)" name="ingredients[0][unit]">
                                <input type="text" class="ingredient-notes" placeholder="备注" name="ingredients[0][notes]">
                                <button type="button" class="btn-remove-ingredient">×</button>
                            </div>
                        </div>
                        <button type="button" id="add-ingredient" class="btn btn-secondary">添加食材</button>
                    </div>
                    
                    <div class="form-group">
                        <label for="tags">标签</label>
                        <input type="text" id="tags" name="tags" class="form-control" placeholder="用逗号分隔标签,如:中式,辣味,健康">
                    </div>
                    
                    <div class="form-actions">
                        <button type="submit" class="btn btn-primary">保存食谱</button>
                        <button type="button" id="cancel-edit" class="btn btn-secondary">取消</button>
                        <button type="button" id="generate-shopping-list" class="btn btn-success" style="display:none;">生成采购清单</button>
                    </div>
                </form>
            </section>
            
            <!-- 采购清单区域 -->
            <section id="shopping-lists" class="shopping-section" style="display:none;">
                <h2>我的采购清单</h2>
                <div class="shopping-lists-container" id="shopping-lists-container">
                    <!-- 采购清单将通过AJAX加载 -->
                </div>
                <div class="shopping-list-editor" id="shopping-list-editor" style="display:none;">
                    <h3 id="shopping-list-title">新建采购清单</h3>
                    <form id="shopping-list-form">
                        <input type="hidden" id="shopping-list-id" name="list_id" value="0">
                        <div class="form-group">
                            <label for="list-name">清单名称</label>
                            <input type="text" id="list-name" name="list_name" required class="form-control">
                        </div>
                        <div class="form-group">
                            <label>清单内容</label>

<div class="shopping-items-container" id="shopping-items-container">

                            <div class="shopping-item-row">
                                <input type="text" class="shopping-item-name" placeholder="物品名称" name="items[0][name]">
                                <input type="number" step="0.01" class="shopping-item-quantity" placeholder="数量" name="items[0][quantity]">
                                <input type="text" class="shopping-item-unit" placeholder="单位" name="items[0][unit]">
                                <div class="item-checkbox">
                                    <input type="checkbox" class="shopping-item-checked" name="items[0][checked]">
                                    <label>已购</label>
                                </div>
                                <button type="button" class="btn-remove-item">×</button>
                            </div>
                        </div>
                        <button type="button" id="add-shopping-item" class="btn btn-secondary">添加物品</button>
                    </div>
                    <div class="form-actions">
                        <button type="submit" class="btn btn-primary">保存清单</button>
                        <button type="button" id="cancel-shopping-edit" class="btn btn-secondary">取消</button>
                    </div>
                </form>
            </div>
        </section>
    </div>
    <?php endif; ?>
</div>

</div>

<?php get_footer(); ?>


### 3.2 添加CSS样式

在子主题的`style.css`文件中添加以下样式:

/ 食谱管理工具样式 /

/ 容器样式 /
.cooking-tools-container {

max-width: 1200px;
margin: 0 auto;
padding: 20px;

}

.recipe-manager-wrapper {

background: #fff;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
overflow: hidden;

}

/ 头部样式 /
.recipe-manager-header {

background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
color: white;
padding: 30px;
text-align: center;

}

.recipe-manager-header h1 {

margin: 0 0 20px 0;
font-size: 2.5em;

}

.user-actions {

display: flex;
justify-content: center;
gap: 15px;
flex-wrap: wrap;

}

/ 按钮样式 /
.btn {

padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
transition: all 0.3s ease;
text-decoration: none;
display: inline-block;

}

.btn-primary {

background-color: #4CAF50;
color: white;

}

.btn-primary:hover {

background-color: #45a049;
transform: translateY(-2px);

}

.btn-secondary {

background-color: #f0f0f0;
color: #333;

}

.btn-secondary:hover {

background-color: #e0e0e0;

}

.btn-success {

background-color: #2196F3;
color: white;

}

.btn-success:hover {

background-color: #0b7dda;

}

/ 内容区域 /
.recipe-manager-content {

padding: 30px;

}

/ 食谱列表样式 /
.recipes-section, .editor-section, .shopping-section {

margin-bottom: 40px;

}

.recipes-section h2, .editor-section h2, .shopping-section h2 {

color: #333;
border-bottom: 2px solid #f0f0f0;
padding-bottom: 10px;
margin-bottom: 20px;

}

/ 筛选区域 /
.recipes-filter {

display: flex;
gap: 15px;
margin-bottom: 20px;
flex-wrap: wrap;

}

.search-input, .filter-select, .form-control {

padding: 10px 15px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 16px;
flex: 1;
min-width: 200px;

}

/ 食谱网格 /
.recipes-grid {

display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 20px;
margin-bottom: 30px;

}

.recipe-card {

background: #fff;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 3px 10px rgba(0,0,0,0.1);
transition: transform 0.3s ease, box-shadow 0.3s ease;
border: 1px solid #eee;

}

.recipe-card:hover {

transform: translateY(-5px);
box-shadow: 0 5px 15px rgba(0,0,0,0.15);

}

.recipe-image {

height: 180px;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
display: flex;
align-items: center;
justify-content: center;
color: #666;

}

.recipe-info {

padding: 20px;

}

.recipe-title {

font-size: 1.3em;
margin: 0 0 10px 0;
color: #333;

}

.recipe-meta {

display: flex;
gap: 15px;
margin-bottom: 15px;
color: #666;
font-size: 0.9em;

}

.recipe-meta span {

display: flex;
align-items: center;
gap: 5px;

}

.recipe-actions {

display: flex;
gap: 10px;
margin-top: 15px;

}

/ 表单样式 /
.form-group {

margin-bottom: 20px;

}

.form-group label {

display: block;
margin-bottom: 8px;
font-weight: 600;
color: #333;

}

.form-row {

display: flex;
gap: 20px;
flex-wrap: wrap;

}

.form-row .form-group {

flex: 1;
min-width: 200px;

}

/ 食材管理 /
.ingredients-container, .shopping-items-container {

border: 1px solid #ddd;
border-radius: 4px;
padding: 15px;
margin-bottom: 15px;
max-height: 300px;
overflow-y: auto;

}

.ingredient-row, .shopping-item-row {

display: flex;
gap: 10px;
margin-bottom: 10px;
align-items: center;
flex-wrap: wrap;

}

.ingredient-row input, .shopping-item-row input {

flex: 1;
min-width: 150px;
padding: 8px 12px;
border: 1px solid #ddd;
border-radius: 4px;

}

.ingredient-name, .shopping-item-name {

min-width: 200px !important;

}

.btn-remove-ingredient, .btn-remove-item {

background: #ff6b6b;
color: white;
border: none;
border-radius: 50%;
width: 30px;
height: 30px;
cursor: pointer;
font-size: 18px;
display: flex;
align-items: center;
justify-content: center;

}

.btn-remove-ingredient:hover, .btn-remove-item:hover {

background: #ff5252;

}

/ 采购清单样式 /
.shopping-lists-container {

display: grid;
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
gap: 20px;

}

.shopping-list-card {

background: #fff;
border-radius: 8px;
padding: 20px;
box-shadow: 0 3px 10px rgba(0,0,0,0.1);
border-left: 4px solid #4CAF50;

}

.shopping-list-header {

display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;

}

.shopping-list-title {

font-size: 1.2em;
margin: 0;
color: #333;

}

.shopping-list-date {

color: #666;
font-size: 0.9em;

}

.shopping-items-list {

margin: 15px 0;

}

.shopping-item {

display: flex;
align-items: center;
padding: 8px 0;
border-bottom: 1px solid #f0f0f0;

}

.shopping-item:last-child {

border-bottom: none;

}

.shopping-item.checked {

opacity: 0.6;
text-decoration: line-through;

}

.item-checkbox {

margin-left: auto;
display: flex;
align-items: center;
gap: 8px;

}

/ 响应式设计 /
@media (max-width: 768px) {

.recipes-grid {
    grid-template-columns: 1fr;
}

.shopping-lists-container {
    grid-template-columns: 1fr;
}

.form-row {
    flex-direction: column;
}

.ingredient-row, .shopping-item-row {
    flex-direction: column;
    align-items: stretch;
}

.ingredient-row input, .shopping-item-row input {
    min-width: 100% !important;
}

}

/ 加载动画 /
.loading-spinner {

text-align: center;
padding: 40px;
color: #666;
font-size: 1.1em;

}

/ 分页样式 /
.pagination {

display: flex;
justify-content: center;
gap: 10px;
margin-top: 30px;

}

.page-number {

padding: 8px 15px;
border: 1px solid #ddd;
border-radius: 4px;
cursor: pointer;
transition: all 0.3s ease;

}

.page-number.active {

background-color: #4CAF50;
color: white;
border-color: #4CAF50;

}

.page-number:hover:not(.active) {

background-color: #f0f0f0;

}


## 第四部分:JavaScript功能实现

### 4.1 创建JavaScript文件

在子主题目录中创建`js/cooking-tools.js`文件:

// 食谱管理工具JavaScript功能

jQuery(document).ready(function($) {

// 初始化变量
let currentPage = 1;
let recipesPerPage = 9;
let currentRecipeId = 0;
let ingredientCounter = 0;
let shoppingItemCounter = 0;

// 初始化模型对象
const cookingToolsModel = {
    // 获取食谱列表
    getRecipes: function(page = 1, search = '', category = '') {
        return $.ajax({
            url: cookingToolsAjax.ajax_url,
            type: 'POST',
            data: {
                action: 'cooking_tools_get_recipes',
                page: page,
                search: search,
                category: category,
                per_page: recipesPerPage,
                nonce: cookingToolsAjax.nonce
            }
        });
    },
    
    // 获取单个食谱
    getRecipe: function(recipeId) {
        return $.ajax({
            url: cookingToolsAjax.ajax_url,
            type: 'POST',
            data: {
                action: 'cooking_tools_get_recipe',
                recipe_id: recipeId,
                nonce: cookingToolsAjax.nonce
            }
        });
    },
    
    // 保存食谱
    saveRecipe: function(recipeData) {
        return $.ajax({
            url: cookingToolsAjax.ajax_url,
            type: 'POST',
            data: {
                action: 'cooking_tools_save_recipe',
                recipe_data: recipeData,
                nonce: cookingToolsAjax.nonce
            }
        });
    },
    
    // 删除食谱
    deleteRecipe: function(recipeId) {
        return $.ajax({
            url: cookingToolsAjax.ajax_url,
            type: 'POST',
            data: {
                action: 'cooking_tools_delete_recipe',
                recipe_id: recipeId,
                nonce: cookingToolsAjax.nonce
            }
        });
    },
    
    // 获取采购清单
    getShoppingLists: function() {
        return $.ajax({
            url: cookingToolsAjax.ajax_url,
            type: 'POST',
            data: {
                action: 'cooking_tools_get_shopping_lists',
                nonce: cookingToolsAjax.nonce
            }
        });
    },
    
    // 保存采购清单
    saveShoppingList: function(listData) {
        return $.ajax({
            url: cookingToolsAjax.ajax_url,
            type: 'POST',
            data: {
                action: 'cooking_tools_save_shopping_list',
                list_data: listData,
                nonce: cookingToolsAjax.nonce
            }
        });
    },
    
    // 删除采购清单
    deleteShoppingList: function(listId) {
        return $.ajax({
            url: cookingToolsAjax.ajax_url,
            type: 'POST',
            data: {
                action: 'cooking_tools_delete_shopping_list',
                list_id: listId,
                nonce: cookingToolsAjax.nonce
            }
        });
    }
};

// 初始化UI组件
const cookingToolsUI = {
    // 显示食谱列表
    showRecipesList: function() {
        $('#recipe-editor').hide();
        $('#shopping-lists').hide();
        $('#recipes-list').show();
        $('#add-new-recipe').text('添加新食谱');
    },
    
    // 显示食谱编辑器
    showRecipeEditor: function(recipeId = 0) {
        $('#recipes-list').hide();
        $('#shopping-lists').hide();
        $('#recipe-editor').show();
        
        if (recipeId === 0) {
            $('#editor-title').text('添加新食谱');
            $('#recipe-id').val(0);
            $('#recipe-form')[0].reset();
            $('#ingredients-container').html(this.createIngredientRow(0));
            ingredientCounter = 1;
            $('#generate-shopping-list').hide();
        } else {
            $('#editor-title').text('编辑食谱');
            $('#generate-shopping-list').show();
        }
        
        $('#add-new-recipe').text('返回食谱列表');
    },
    
    // 显示采购清单
    showShoppingLists: function() {
        $('#recipes-list').hide();
        $('#recipe-editor').hide();
        $('#shopping-lists').show();
        $('#add-new-recipe').text('返回食谱列表');
    },
    
    // 创建食材行
    createIngredientRow: function(index) {
        return `
            <div class="ingredient-row">
                <input type="text" class="ingredient-name" placeholder="食材名称" name="ingredients[${index}][name]">
                <input type="number" step="0.01" class="ingredient-quantity" placeholder="数量" name="ingredients[${index}][quantity]">
                <input type="text" class="ingredient-unit" placeholder="单位 (克/个/汤匙等)" name="ingredients[${index}][unit]">
                <input type="text" class="ingredient-notes" placeholder="备注" name="ingredients[${index}][notes]">
                <button type="button" class="btn-remove-ingredient">×</button>
            </div>
        `;
    },
    
    // 创建采购物品行
    createShoppingItemRow: function(index) {
        return `
            <div class="shopping-item-row">
                <input type="text" class="shopping-item-name" placeholder="物品名称" name="items[${index}][name]">
                <input type="number" step="0.01" class="shopping-item-quantity" placeholder="数量" name="items[${index}][quantity]">
                <input type="text" class="shopping-item-unit" placeholder="单位" name="items[${index}][unit]">
                <div class="item-checkbox">
                    <input type="checkbox" class="shopping-item-checked" name="items[${index}][checked]">
                    <label>已购</label>
                </div>
                <button type="button" class="btn-remove-item">×</button>
            </div>
        `;
    },
    
    // 渲染食谱卡片
    renderRecipeCard: function(recipe) {
        const prepTime = recipe.prep_time ? `${recipe.prep_time}分钟` : '未设置';
        const cookTime = recipe.cook_time ? `${recipe.cook_time}分钟` : '未设置';
        const servings = recipe.servings ? `${recipe.servings}人份` : '未设置';
        
        return `
            <div class="recipe-card" data-recipe-id="${recipe.id}">
                <div class="recipe-image">
                    ${recipe.featured_image ? 
                        `<img src="${recipe.featured_image}" alt="${recipe.recipe_title}" style="width:100%;height:100%;object-fit:cover;">` : 
                        '<span>暂无图片</span>'
                    }
                </div>
                <div class="recipe-info">
                    <h3 class="recipe-title">${recipe.recipe_title}</h3>
                    <div class="recipe-meta">
                        <span title="准备时间">⏱️ ${prepTime}</span>
                        <span title="烹饪时间">🔥 ${cookTime}</span>
                        <span title="份量">👥 ${servings}</span>
                    </div>
                    <div class="recipe-category">
                        <span class="category-badge">${recipe.category || '未分类'}</span>
                        ${recipe.difficulty ? `<span class="difficulty-badge">${recipe.difficulty}</span>` : ''}
                    </div>
                    <div class="recipe-actions">
                        <button class="btn btn-secondary btn-view-recipe" data-id="${recipe.id}">查看</button>
                        <button class="btn btn-primary btn-edit-recipe" data-id="${recipe.id}">编辑</button>
                        <button class="btn btn-danger btn-delete-recipe" data-id="${recipe.id}">删除</button>
                    </div>
                </div>
            </div>
       
本文来自网络,不代表柔性供应链服务中心立场,转载请注明出处:https://mall.org.cn/5198.html

EXCHANGES®作者

上一篇
下一篇

为您推荐

发表回复

联系我们

联系我们

18559313275

在线咨询: QQ交谈

邮箱: vip@exchanges.center

工作时间:周一至周五,9:00-17:30,节假日休息
返回顶部