420 lines
22 KiB
HTML
420 lines
22 KiB
HTML
|
|
<!DOCTYPE html>
|
|||
|
|
<html class="x-admin-sm">
|
|||
|
|
|
|||
|
|
<head>
|
|||
|
|
<meta charset="UTF-8">
|
|||
|
|
<title>菜谱管理</title>
|
|||
|
|
<meta name="renderer" content="webkit">
|
|||
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
|||
|
|
<meta name="viewport" content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi" />
|
|||
|
|
<link rel="stylesheet" href="/x_admin/css/font.css">
|
|||
|
|
<link rel="stylesheet" href="/x_admin/css/xadmin.css">
|
|||
|
|
<script type="text/javascript" src="/x_admin/lib/layui/layui.js" charset="utf-8"></script>
|
|||
|
|
<script type="text/javascript" src="/x_admin/js/xadmin.js"></script>
|
|||
|
|
<script type="text/javascript" src="/x_admin/js/jq.js"></script>
|
|||
|
|
<style>
|
|||
|
|
.step-container {
|
|||
|
|
display: flex;
|
|||
|
|
margin-bottom: 15px;
|
|||
|
|
border: 1px solid #eee;
|
|||
|
|
padding: 15px;
|
|||
|
|
border-radius: 4px;
|
|||
|
|
}
|
|||
|
|
.step-content {
|
|||
|
|
flex: 1;
|
|||
|
|
padding-right: 15px;
|
|||
|
|
}
|
|||
|
|
.step-image {
|
|||
|
|
width: 200px;
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: column;
|
|||
|
|
align-items: center;
|
|||
|
|
}
|
|||
|
|
.step-preview {
|
|||
|
|
max-width: 100%;
|
|||
|
|
max-height: 150px;
|
|||
|
|
margin-bottom: 10px;
|
|||
|
|
display: none;
|
|||
|
|
}
|
|||
|
|
.step-buttons {
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
margin-top: 10px;
|
|||
|
|
}
|
|||
|
|
</style>
|
|||
|
|
</head>
|
|||
|
|
<body>
|
|||
|
|
<div class="layui-fluid">
|
|||
|
|
<div class="layui-row">
|
|||
|
|
<form class="layui-form layui-form-pane">
|
|||
|
|
<div class="layui-form-item">
|
|||
|
|
<label class="layui-form-label" style="width: 120px; text-align: right;">
|
|||
|
|
<span class="x-red">☆</span>菜谱标题
|
|||
|
|
</label>
|
|||
|
|
<div class="layui-input-inline" style="width: 80%;">
|
|||
|
|
<input type="text" id="recipe_title" name="recipe_title" required lay-verify="required" autocomplete="off" class="layui-input">
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
<!-- 图片选择器html部分 -->
|
|||
|
|
<div class="layui-form-item">
|
|||
|
|
<label class="layui-form-label" style="width: 120px; text-align: right;">
|
|||
|
|
<span class="x-red">★</span>选择封面
|
|||
|
|
</label>
|
|||
|
|
<div class="layui-input-inline">
|
|||
|
|
<div class="layui-btn" onclick="openImageManager('preview_img', 'cove_img')">点击选择</div>
|
|||
|
|
<input type="hidden" id="cove_img" name="cove_img">
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="layui-form-item">
|
|||
|
|
<label class="layui-form-label" style="width: 120px; text-align: right;">
|
|||
|
|
<span class="x-red"></span>预览
|
|||
|
|
</label>
|
|||
|
|
<div class="layui-input-inline">
|
|||
|
|
<img id="preview_img" style="max-width: 200px; display: none; border: 1px solid #eee; margin-top: 10px;" src="" alt="">
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
<!-- 图片选择器html部分 -->
|
|||
|
|
<div class="layui-form-item">
|
|||
|
|
<label class="layui-form-label" style="width: 120px; text-align: right;">
|
|||
|
|
<span class="x-red">☆</span>菜谱类型
|
|||
|
|
</label>
|
|||
|
|
<div class="layui-input-inline" style="width: 80%;">
|
|||
|
|
<select name="recipe_type" lay-verify="required" id="recipe_type">
|
|||
|
|
<option value="0">请选择菜谱类型</option>
|
|||
|
|
{volist name="result" id="vo"}
|
|||
|
|
<option value="{$vo.id}">{$vo.name}</option>
|
|||
|
|
{/volist}
|
|||
|
|
</select>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="layui-form-item">
|
|||
|
|
<label class="layui-form-label" style="width: 120px; text-align: right;">
|
|||
|
|
<span class="x-red">☆</span>菜谱描述
|
|||
|
|
</label>
|
|||
|
|
<div class="layui-input-inline" style="width: 80%;">
|
|||
|
|
<textarea name="recipe_desc" id="recipe_desc" required lay-verify="required" placeholder="请输入菜谱描述" class="layui-textarea"></textarea>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="layui-form-item">
|
|||
|
|
<label class="layui-form-label" style="width: 120px; text-align: right;">
|
|||
|
|
<span class="x-red">☆</span>食材
|
|||
|
|
</label>
|
|||
|
|
<div class="layui-input-inline" style="width: 80%;">
|
|||
|
|
<div id="ingredients_container">
|
|||
|
|
<div class="layui-form-item ingredient-item" style="margin-bottom: 10px;">
|
|||
|
|
<div class="layui-inline">
|
|||
|
|
<input type="text" name="ingredient_name[]" placeholder="食材名称" autocomplete="off" class="layui-input ingredient-name" style="width: 150px; display: inline-block;">
|
|||
|
|
<div class="ingredient-suggest" style="position: absolute; z-index: 999; display: none; width: 150px; max-height: 200px; overflow-y: auto; border: 1px solid #d2d2d2; background: #fff;"></div>
|
|||
|
|
<input type="text" name="ingredient_amount[]" placeholder="用量(g)" autocomplete="off" class="layui-input" style="width: 100px; display: inline-block; margin-left: 10px;">
|
|||
|
|
<button type="button" class="layui-btn layui-btn-danger layui-btn-xs remove-ingredient" style="margin-left: 10px;">删除</button>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
<button type="button" id="add_ingredient" class="layui-btn layui-btn-xs">添加食材</button>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="layui-form-item">
|
|||
|
|
<label class="layui-form-label" style="width: 120px; text-align: right;">
|
|||
|
|
<span class="x-red">☆</span>步骤
|
|||
|
|
</label>
|
|||
|
|
<div class="layui-input-inline" style="width: 80%;">
|
|||
|
|
<div id="steps_container">
|
|||
|
|
<div class="step-container">
|
|||
|
|
<div class="step-content">
|
|||
|
|
<label class="layui-form-label" style="width: auto; padding: 9px 5px; text-align: left;">步骤1</label>
|
|||
|
|
<textarea name="step_desc[]" placeholder="请输入步骤描述" class="layui-textarea"></textarea>
|
|||
|
|
</div>
|
|||
|
|
<div class="step-image">
|
|||
|
|
<img class="step-preview" src="" alt="步骤图片预览">
|
|||
|
|
<input type="hidden" class="step-image-id" name="step_image[]" value="">
|
|||
|
|
<div class="step-buttons">
|
|||
|
|
<button type="button" class="layui-btn layui-btn-xs select-step-image">选择图片</button>
|
|||
|
|
<button type="button" class="layui-btn layui-btn-danger layui-btn-xs remove-step">删除步骤</button>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
<button type="button" id="add_step" class="layui-btn layui-btn-xs">添加步骤</button>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="layui-form-item" style="display: flex;flex-direction: row;justify-content: center;">
|
|||
|
|
<button class="layui-btn" lay-filter="add" lay-submit="" style="width: 150px;">增加</button>
|
|||
|
|
</div>
|
|||
|
|
</form>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
<script>
|
|||
|
|
// 图片选择器js部分~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|||
|
|
// 全局变量存储当前操作的预览和隐藏字段ID
|
|||
|
|
var currentImageSelection = {
|
|||
|
|
previewId: '',
|
|||
|
|
hiddenFieldId: ''
|
|||
|
|
};
|
|||
|
|
// 打开图片管理器函数
|
|||
|
|
function openImageManager(previewId, hiddenFieldId) {
|
|||
|
|
// 存储当前操作的ID
|
|||
|
|
currentImageSelection.previewId = previewId;
|
|||
|
|
currentImageSelection.hiddenFieldId = hiddenFieldId;
|
|||
|
|
|
|||
|
|
// 打开图片管理窗口
|
|||
|
|
xadmin.open('图片管理', '/k/admin/pic', '80%', '80%');
|
|||
|
|
}
|
|||
|
|
// 接收从图片管理窗口返回的参数
|
|||
|
|
function receiveParamFromIframe(param) {
|
|||
|
|
if(param.length > 0 && currentImageSelection.previewId && currentImageSelection.hiddenFieldId){
|
|||
|
|
// 更新预览图片
|
|||
|
|
var img = document.getElementById(currentImageSelection.previewId);
|
|||
|
|
img.src = param[1];
|
|||
|
|
img.style.display = 'block';
|
|||
|
|
|
|||
|
|
// 更新隐藏字段值
|
|||
|
|
document.getElementById(currentImageSelection.hiddenFieldId).value = param[0];
|
|||
|
|
|
|||
|
|
// 重置当前操作的ID
|
|||
|
|
currentImageSelection.previewId = '';
|
|||
|
|
currentImageSelection.hiddenFieldId = '';
|
|||
|
|
} else {
|
|||
|
|
layer.msg('图片选择失败');
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
// 图片选择器js部分~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|||
|
|
$(document).ready(function(){
|
|||
|
|
var stepCounter = 1;
|
|||
|
|
var ingredientCounter = 1;
|
|||
|
|
|
|||
|
|
// 添加食材
|
|||
|
|
$('#add_ingredient').on('click', function() {
|
|||
|
|
ingredientCounter++;
|
|||
|
|
var html = `
|
|||
|
|
<div class="layui-form-item ingredient-item" style="margin-bottom: 10px;">
|
|||
|
|
<div class="layui-inline">
|
|||
|
|
<input type="text" name="ingredient_name[]" placeholder="食材名称" autocomplete="off" class="layui-input ingredient-name" style="width: 150px; display: inline-block;">
|
|||
|
|
<div class="ingredient-suggest" style="position: absolute; z-index: 999; display: none; width: 150px; max-height: 200px; overflow-y: auto; border: 1px solid #d2d2d2; background: #fff;"></div>
|
|||
|
|
<input type="text" name="ingredient_amount[]" placeholder="用量(g)" autocomplete="off" class="layui-input" style="width: 100px; display: inline-block; margin-left: 10px;">
|
|||
|
|
<button type="button" class="layui-btn layui-btn-danger layui-btn-xs remove-ingredient" style="margin-left: 10px;">删除</button>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
`;
|
|||
|
|
$('#ingredients_container').append(html);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 食材名称输入自动完成
|
|||
|
|
$(document).on('input', '.ingredient-name', function() {
|
|||
|
|
var input = $(this);
|
|||
|
|
var keyword = input.val().trim();
|
|||
|
|
var suggestBox = input.next('.ingredient-suggest');
|
|||
|
|
|
|||
|
|
if (keyword.length < 1) {
|
|||
|
|
suggestBox.hide();
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
console.log(keyword)
|
|||
|
|
// 发送AJAX请求
|
|||
|
|
$.ajax({
|
|||
|
|
url: '/k/a/cookbook/find_food_list',
|
|||
|
|
dataType:"json", //返回格式为json
|
|||
|
|
async:true,//请求是否异步,默认为异步,这也是ajax重要特性
|
|||
|
|
data:{"id":"value"}, //参数值
|
|||
|
|
data: {'search_data': keyword},
|
|||
|
|
type: 'POST',
|
|||
|
|
success: function(res) {
|
|||
|
|
if (res.code === 0 && res.data && res.data.length > 0) {
|
|||
|
|
var html = '';
|
|||
|
|
res.data.forEach(function(item) {
|
|||
|
|
html += '<div class="suggest-item" style="padding: 5px 10px; cursor: pointer;" data-id="' + item.id + '" data-name="' + item.food_name + '" data-kcal="' + item.Calorie_val + '">' + item.food_name + '</div>';
|
|||
|
|
});
|
|||
|
|
suggestBox.html(html).show();
|
|||
|
|
} else {
|
|||
|
|
suggestBox.hide();
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
error: function() {
|
|||
|
|
suggestBox.hide();
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 点击建议项填充到输入框
|
|||
|
|
$(document).on('click', '.suggest-item', function() {
|
|||
|
|
var id = $(this).data('id');
|
|||
|
|
var name = $(this).data('name');
|
|||
|
|
var kcal = $(this).data('kcal');
|
|||
|
|
|
|||
|
|
var parentDiv = $(this).closest('.layui-inline');
|
|||
|
|
parentDiv.find('.ingredient-name').val(name).data('id', id).data('kcal', kcal);
|
|||
|
|
parentDiv.find('.ingredient-suggest').hide();
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 点击其他地方隐藏建议框并清空输入框
|
|||
|
|
$(document).on('click', function(e) {
|
|||
|
|
if (!$(e.target).closest('.ingredient-suggest').length && !$(e.target).hasClass('ingredient-name')) {
|
|||
|
|
$('.ingredient-suggest').hide();
|
|||
|
|
// 清空未选择食材的输入框
|
|||
|
|
$('.ingredient-name').each(function() {
|
|||
|
|
if (!$(this).data('id')) { // 如果没有选择过食材(没有data-id)
|
|||
|
|
$(this).val(''); // 清空输入框
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 删除食材
|
|||
|
|
$(document).on('click', '.remove-ingredient', function() {
|
|||
|
|
if($('.ingredient-item').length > 1) {
|
|||
|
|
$(this).closest('.ingredient-item').remove();
|
|||
|
|
} else {
|
|||
|
|
layer.msg('至少保留一个食材');
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 添加步骤
|
|||
|
|
$('#add_step').on('click', function() {
|
|||
|
|
stepCounter++;
|
|||
|
|
var html = `
|
|||
|
|
<div class="step-container">
|
|||
|
|
<div class="step-content">
|
|||
|
|
<label class="layui-form-label" style="width: auto; padding: 9px 5px; text-align: left;">步骤${stepCounter}</label>
|
|||
|
|
<textarea name="step_desc[]" placeholder="请输入步骤描述" class="layui-textarea"></textarea>
|
|||
|
|
</div>
|
|||
|
|
<div class="step-image">
|
|||
|
|
<img class="step-preview" src="" alt="步骤图片预览">
|
|||
|
|
<input type="hidden" class="step-image-id" name="step_image[]" value="">
|
|||
|
|
<div class="step-buttons">
|
|||
|
|
<button type="button" class="layui-btn layui-btn-xs select-step-image">选择图片</button>
|
|||
|
|
<button type="button" class="layui-btn layui-btn-danger layui-btn-xs remove-step">删除步骤</button>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
`;
|
|||
|
|
$('#steps_container').append(html);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 为步骤选择图片
|
|||
|
|
$(document).on('click', '.select-step-image', function() {
|
|||
|
|
var container = $(this).closest('.step-container');
|
|||
|
|
var previewImg = container.find('.step-preview');
|
|||
|
|
var hiddenInput = container.find('.step-image-id');
|
|||
|
|
|
|||
|
|
// 为元素设置唯一ID
|
|||
|
|
var previewId = 'step-preview-' + Math.random().toString(36).substr(2, 9);
|
|||
|
|
var hiddenId = 'step-image-' + Math.random().toString(36).substr(2, 9);
|
|||
|
|
|
|||
|
|
previewImg.attr('id', previewId);
|
|||
|
|
hiddenInput.attr('id', hiddenId);
|
|||
|
|
|
|||
|
|
// 打开图片管理器
|
|||
|
|
openImageManager(previewId, hiddenId);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 删除步骤
|
|||
|
|
$(document).on('click', '.remove-step', function() {
|
|||
|
|
if($('.step-container').length > 1) {
|
|||
|
|
$(this).closest('.step-container').remove();
|
|||
|
|
// 重新编号步骤
|
|||
|
|
$('.step-container').each(function(index) {
|
|||
|
|
$(this).find('.layui-form-label').text('步骤' + (index + 1));
|
|||
|
|
});
|
|||
|
|
stepCounter--;
|
|||
|
|
} else {
|
|||
|
|
layer.msg('至少保留一个步骤');
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 表单提交时收集数据
|
|||
|
|
layui.use(['form', 'layer'], function() {
|
|||
|
|
var form = layui.form,
|
|||
|
|
layer = layui.layer;
|
|||
|
|
|
|||
|
|
// 监听提交
|
|||
|
|
form.on('submit(add)', function(data) {
|
|||
|
|
// 显示加载中
|
|||
|
|
var loadIndex = layer.load(1);
|
|||
|
|
|
|||
|
|
// 收集表单数据
|
|||
|
|
var formData = {
|
|||
|
|
cook_label: $('#recipe_type').val(),
|
|||
|
|
title: $('#recipe_title').val(),
|
|||
|
|
description: $('#recipe_desc').val(),
|
|||
|
|
cover: $('#cove_img').val(), // 封面图片ID
|
|||
|
|
foodList: [],
|
|||
|
|
stepList: []
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 收集食材数据
|
|||
|
|
$('.ingredient-item').each(function() {
|
|||
|
|
var nameInput = $(this).find('.ingredient-name');
|
|||
|
|
var amountInput = $(this).find('input[placeholder="用量(g)"]');
|
|||
|
|
|
|||
|
|
var id = nameInput.data('id');
|
|||
|
|
var name = nameInput.val();
|
|||
|
|
var weight = amountInput.val();
|
|||
|
|
|
|||
|
|
if (id && name && weight && weight > 0) {
|
|||
|
|
formData.foodList.push({
|
|||
|
|
id: id,
|
|||
|
|
name: name,
|
|||
|
|
weight: weight
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 收集步骤数据
|
|||
|
|
$('.step-container').each(function() {
|
|||
|
|
var desc = $(this).find('textarea').val();
|
|||
|
|
var imageId = $(this).find('.step-image-id').val();
|
|||
|
|
|
|||
|
|
if (desc && desc.trim() !== '') {
|
|||
|
|
formData.stepList.push({
|
|||
|
|
pic_list: [imageId] || [],
|
|||
|
|
description: desc.trim()
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 调试输出
|
|||
|
|
console.log('提交数据:', formData);
|
|||
|
|
|
|||
|
|
// 发送AJAX请求
|
|||
|
|
$.ajax({
|
|||
|
|
url: "/k/a/cookbook/add_cookbook_action",
|
|||
|
|
type: "POST",
|
|||
|
|
data: JSON.stringify(formData),
|
|||
|
|
contentType: "application/json",
|
|||
|
|
success: function(res) {
|
|||
|
|
layer.close(loadIndex);
|
|||
|
|
if (res.code === 0) {
|
|||
|
|
layer.alert("添加成功", {icon: 1}, function() {
|
|||
|
|
xadmin.close();
|
|||
|
|
xadmin.father_reload();
|
|||
|
|
});
|
|||
|
|
} else {
|
|||
|
|
layer.alert("添加失败:" + res.msg, {icon: 2});
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
error: function() {
|
|||
|
|
layer.close(loadIndex);
|
|||
|
|
layer.alert("请求失败,请稍后再试", {icon: 2});
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
return false;
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
//加载提示开启
|
|||
|
|
function load() {
|
|||
|
|
var index = layer.load(1, {
|
|||
|
|
shade: [0.1, '#fff'] //0.1透明度的白色背景
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
// 关闭加载提示
|
|||
|
|
function c_load() {
|
|||
|
|
layer.close(layer.index)
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
</script>
|
|||
|
|
</body>
|
|||
|
|
</html>
|