612 lines
21 KiB
PHP
612 lines
21 KiB
PHP
<?php
|
|
/**
|
|
* 🍽️ 今天吃什么 - 智能筛选接口
|
|
*
|
|
* @file api_what_to_eat.php
|
|
* @author AI Assistant
|
|
* @date 2026-04-10
|
|
* @version 1.26.0
|
|
* @desc 提供动态筛选、随机推荐、菜谱详情查询功能
|
|
* @lastUpdate 2026-04-12 添加评分显示功能,更新字段名 rate_nums/rate_score
|
|
*/
|
|
|
|
$startTime = microtime(true);
|
|
|
|
require '../zb_system/function/c_system_base.php';
|
|
$zbp->Load();
|
|
|
|
require_once 'cache.php';
|
|
require_once 'response.php';
|
|
|
|
header('Content-Type: application/json; charset=utf-8');
|
|
header('Access-Control-Allow-Origin: *');
|
|
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
|
|
http_response_code(200);
|
|
exit;
|
|
}
|
|
|
|
$method = $_SERVER['REQUEST_METHOD'];
|
|
|
|
if ($method === 'GET') {
|
|
$act = strtolower(trim($_GET['act'] ?? 'index'));
|
|
$params = $_GET;
|
|
} elseif ($method === 'POST') {
|
|
$input = file_get_contents('php://input');
|
|
$jsonData = json_decode($input, true);
|
|
|
|
if (is_array($jsonData)) {
|
|
$params = $jsonData;
|
|
} else {
|
|
$params = $_POST;
|
|
}
|
|
|
|
$act = strtolower(trim($params['act'] ?? 'index'));
|
|
} else {
|
|
$act = 'index';
|
|
$params = array();
|
|
}
|
|
|
|
$result = array();
|
|
|
|
switch ($act) {
|
|
case 'filter_steps':
|
|
$result = get_filter_steps();
|
|
break;
|
|
case 'filter_apply':
|
|
$result = apply_filter();
|
|
break;
|
|
case 'detail':
|
|
$result = get_recipe_detail();
|
|
break;
|
|
case 'index':
|
|
default:
|
|
$result = get_index();
|
|
break;
|
|
}
|
|
|
|
$result['_query_time'] = round((microtime(true) - $startTime) * 1000, 2) . 'ms';
|
|
|
|
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
|
exit;
|
|
|
|
/**
|
|
* 接口索引
|
|
* @return array
|
|
*/
|
|
function get_index() {
|
|
return array(
|
|
'code' => 200,
|
|
'message' => 'success',
|
|
'data' => array(
|
|
'description' => '🍽️ 今天吃什么 - 智能筛选接口',
|
|
'version' => '1.25.0',
|
|
'methods' => array('GET', 'POST'),
|
|
'endpoints' => array(
|
|
'filter_steps' => '?act=filter_steps',
|
|
'filter_steps_with_category' => '?act=filter_steps&category=13',
|
|
'filter_apply' => '?act=filter_apply&category=13&tag=2&count=5',
|
|
'detail_by_id' => '?act=detail&id=1234',
|
|
'detail_by_title' => '?act=detail&title=宫保鸡丁',
|
|
'detail_by_code' => '?act=detail&code=CP001234',
|
|
'detail_fuzzy' => '?act=detail&title=鸡丁&fuzzy=1'
|
|
),
|
|
'features' => array(
|
|
'dynamic_filter' => '逐步筛选,越选越精准',
|
|
'random_recommend' => '随机推荐,每次不同',
|
|
'multi_lookup' => '支持ID/标题/编码查询'
|
|
)
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* 获取筛选步骤
|
|
* @return array
|
|
*/
|
|
function get_filter_steps() {
|
|
global $zbp, $params;
|
|
|
|
$selectedCategories = isset($params['category']) ? array_map('intval', array_filter(explode(',', $params['category']))) : array();
|
|
$selectedTags = isset($params['tag']) ? array_map('intval', array_filter(explode(',', $params['tag']))) : array();
|
|
$parentCategory = isset($params['parent_category']) ? (int) $params['parent_category'] : 0;
|
|
|
|
$cacheKey = 'filter_steps_' . md5(serialize($params));
|
|
$cached = ApiCache::get('filter_steps', $params, 300);
|
|
if ($cached !== null) {
|
|
return $cached;
|
|
}
|
|
|
|
$tablePost = $zbp->db->dbpre . 'post';
|
|
$tableCategory = $zbp->db->dbpre . 'category';
|
|
$tableTag = $zbp->db->dbpre . 'tag';
|
|
|
|
$whereClauses = array("p.log_Type = 0", "p.log_Status = 0");
|
|
|
|
if (!empty($selectedCategories)) {
|
|
$cateList = implode(',', $selectedCategories);
|
|
$whereClauses[] = "p.log_CateID IN ($cateList)";
|
|
}
|
|
|
|
if (!empty($selectedTags)) {
|
|
$tagConditions = array();
|
|
foreach ($selectedTags as $tagId) {
|
|
$tagConditions[] = "p.log_Tag LIKE '%{{$tagId}}%'";
|
|
}
|
|
if (!empty($tagConditions)) {
|
|
$whereClauses[] = "(" . implode(' OR ', $tagConditions) . ")";
|
|
}
|
|
}
|
|
|
|
$whereSql = implode(' AND ', $whereClauses);
|
|
$countSql = "SELECT COUNT(*) as cnt FROM $tablePost p WHERE $whereSql";
|
|
$countResult = $zbp->db->Query($countSql);
|
|
$matchedCount = (int) ($countResult[0]['cnt'] ?? 0);
|
|
|
|
$steps = array(
|
|
array(
|
|
'step' => 1,
|
|
'name' => '菜系分类',
|
|
'field' => 'category',
|
|
'description' => '选择你喜欢的菜系',
|
|
'required' => false,
|
|
'completed' => !empty($selectedCategories),
|
|
'selected' => $selectedCategories
|
|
),
|
|
array(
|
|
'step' => 2,
|
|
'name' => '烹饪方式',
|
|
'field' => 'tag',
|
|
'description' => '选择烹饪方法',
|
|
'required' => false,
|
|
'completed' => !empty($selectedTags),
|
|
'selected' => $selectedTags
|
|
),
|
|
array(
|
|
'step' => 3,
|
|
'name' => '口味偏好',
|
|
'field' => 'taste',
|
|
'description' => '选择口味类型',
|
|
'required' => false,
|
|
'completed' => false,
|
|
'selected' => array()
|
|
),
|
|
array(
|
|
'step' => 4,
|
|
'name' => '功效需求',
|
|
'field' => 'effect',
|
|
'description' => '选择功效类型',
|
|
'required' => false,
|
|
'completed' => false,
|
|
'selected' => array()
|
|
)
|
|
);
|
|
|
|
$currentStep = 1;
|
|
foreach ($steps as $i => $step) {
|
|
if (!$step['completed']) {
|
|
$currentStep = $step['step'];
|
|
break;
|
|
}
|
|
}
|
|
|
|
$availableOptions = array();
|
|
|
|
$parentSql = "SELECT cate_ID, cate_Name, cate_Count
|
|
FROM $tableCategory
|
|
WHERE cate_ParentID = 0
|
|
ORDER BY cate_Order ASC";
|
|
$parentResults = $zbp->db->Query($parentSql);
|
|
|
|
foreach ($parentResults as $parentRow) {
|
|
$parentId = (int) $parentRow['cate_ID'];
|
|
$parentName = $parentRow['cate_Name'];
|
|
|
|
$childSql = "SELECT c.cate_ID, c.cate_Name, COUNT(p.log_ID) as recipe_count
|
|
FROM $tableCategory c
|
|
LEFT JOIN $tablePost p ON p.log_CateID = c.cate_ID AND p.log_Type = 0 AND p.log_Status = 0";
|
|
|
|
$childWhereClauses = $whereClauses;
|
|
$childWhereClauses[0] = "p.log_Type = 0";
|
|
$childWhereClauses[1] = "p.log_Status = 0";
|
|
|
|
$childWhereSql = implode(' AND ', $childWhereClauses);
|
|
$childSql .= " WHERE c.cate_ParentID = $parentId AND ($childWhereSql OR p.log_ID IS NULL) GROUP BY c.cate_ID, c.cate_Name HAVING recipe_count > 0 ORDER BY recipe_count DESC LIMIT 10";
|
|
|
|
$childResults = $zbp->db->Query($childSql);
|
|
$children = array();
|
|
|
|
foreach ($childResults as $childRow) {
|
|
$children[] = array(
|
|
'id' => (int) $childRow['cate_ID'],
|
|
'name' => $childRow['cate_Name'],
|
|
'count' => (int) $childRow['recipe_count']
|
|
);
|
|
}
|
|
|
|
if (!empty($children)) {
|
|
$availableOptions[] = array(
|
|
'id' => $parentId,
|
|
'name' => $parentName,
|
|
'type' => 'parent',
|
|
'children_count' => count($children),
|
|
'children' => $children
|
|
);
|
|
}
|
|
}
|
|
|
|
$result = array(
|
|
'code' => 200,
|
|
'message' => 'success',
|
|
'data' => array(
|
|
'current_step' => $currentStep,
|
|
'total_steps' => count($steps),
|
|
'steps' => $steps,
|
|
'available_options' => $availableOptions,
|
|
'matched_count' => $matchedCount,
|
|
'can_skip' => true,
|
|
'can_apply' => $matchedCount > 0
|
|
)
|
|
);
|
|
|
|
ApiCache::set('filter_steps', $params, $result, 300);
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* 应用筛选条件
|
|
* @return array
|
|
*/
|
|
function apply_filter() {
|
|
global $zbp, $params;
|
|
|
|
$categories = isset($params['category']) ? array_map('intval', array_filter(explode(',', $params['category']))) : array();
|
|
$tags = isset($params['tag']) ? array_map('intval', array_filter(explode(',', $params['tag']))) : array();
|
|
$count = isset($params['count']) ? min((int) $params['count'], 20) : 5;
|
|
$count = max($count, 1);
|
|
|
|
$tablePost = $zbp->db->dbpre . 'post';
|
|
$tableCategory = $zbp->db->dbpre . 'category';
|
|
$tableTag = $zbp->db->dbpre . 'tag';
|
|
$tablePostStat = $zbp->db->dbpre . 'post_stat';
|
|
|
|
$whereClauses = array("p.log_Type = 0", "p.log_Status = 0");
|
|
|
|
if (!empty($categories)) {
|
|
$cateList = implode(',', $categories);
|
|
$whereClauses[] = "p.log_CateID IN ($cateList)";
|
|
}
|
|
|
|
if (!empty($tags)) {
|
|
$tagConditions = array();
|
|
foreach ($tags as $tagId) {
|
|
$tagConditions[] = "p.log_Tag LIKE '%{{$tagId}}%'";
|
|
}
|
|
if (!empty($tagConditions)) {
|
|
$whereClauses[] = "(" . implode(' OR ', $tagConditions) . ")";
|
|
}
|
|
}
|
|
|
|
$whereSql = implode(' AND ', $whereClauses);
|
|
|
|
$countSql = "SELECT COUNT(*) as cnt FROM $tablePost p WHERE $whereSql";
|
|
$countResult = $zbp->db->Query($countSql);
|
|
$totalMatched = (int) ($countResult[0]['cnt'] ?? 0);
|
|
|
|
if ($totalMatched === 0) {
|
|
return array(
|
|
'code' => 404,
|
|
'message' => '没有找到符合条件的菜谱',
|
|
'data' => array(
|
|
'recipes' => array(),
|
|
'total_matched' => 0,
|
|
'returned_count' => 0,
|
|
'filters_applied' => array(
|
|
'category' => $categories,
|
|
'tag' => $tags
|
|
),
|
|
'suggestions' => array(
|
|
'尝试减少筛选条件',
|
|
'更换分类或标签'
|
|
)
|
|
)
|
|
);
|
|
}
|
|
|
|
$sql = "SELECT p.log_ID, p.log_Title, p.log_Intro, p.log_CateID, p.log_Tag, p.log_ViewNums,
|
|
c.cate_Name,
|
|
COALESCE(s.like_nums, 0) as like_nums,
|
|
COALESCE(s.rate_nums, 0) as rate_nums,
|
|
COALESCE(s.rate_score, 0) as rate_score
|
|
FROM $tablePost p
|
|
LEFT JOIN $tableCategory c ON p.log_CateID = c.cate_ID
|
|
LEFT JOIN $tablePostStat s ON p.log_ID = s.log_id
|
|
WHERE $whereSql
|
|
ORDER BY RAND()
|
|
LIMIT $count";
|
|
|
|
$results = $zbp->db->Query($sql);
|
|
|
|
$recipes = array();
|
|
foreach ($results as $row) {
|
|
$recipeId = (int) $row['log_ID'];
|
|
|
|
$tagIds = array_filter(array_map('intval', explode(',', $row['log_Tag'] ?? '')));
|
|
$tagsList = array();
|
|
if (!empty($tagIds)) {
|
|
$tagIdList = implode(',', $tagIds);
|
|
$tagSql = "SELECT tag_ID, tag_Name FROM $tableTag WHERE tag_ID IN ($tagIdList)";
|
|
$tagResults = $zbp->db->Query($tagSql);
|
|
foreach ($tagResults as $tagRow) {
|
|
$tagsList[] = array(
|
|
'id' => (int) $tagRow['tag_ID'],
|
|
'name' => $tagRow['tag_Name']
|
|
);
|
|
}
|
|
}
|
|
|
|
$recipes[] = array(
|
|
'id' => $recipeId,
|
|
'code' => 'CP' . str_pad($recipeId, 6, '0', STR_PAD_LEFT),
|
|
'title' => $row['log_Title'],
|
|
'intro' => mb_substr(strip_tags($row['log_Intro'] ?? ''), 0, 100),
|
|
'category' => array(
|
|
'id' => (int) ($row['log_CateID'] ?? 0),
|
|
'name' => $row['cate_Name'] ?? ''
|
|
),
|
|
'tags' => $tagsList,
|
|
'statistics' => array(
|
|
'view' => (int) ($row['log_ViewNums'] ?? 0),
|
|
'like' => (int) ($row['like_nums'] ?? 0),
|
|
'rate_count' => (int) ($row['rate_nums'] ?? 0),
|
|
'rate_score' => (float) ($row['rate_score'] ?? 0)
|
|
),
|
|
'rating' => ApiResponse::getRatingSummary(
|
|
(float) ($row['rate_score'] ?? 0),
|
|
(int) ($row['rate_nums'] ?? 0)
|
|
)
|
|
);
|
|
}
|
|
|
|
$refreshParams = array('act' => 'filter_apply', 'count' => $count);
|
|
if (!empty($categories)) {
|
|
$refreshParams['category'] = implode(',', $categories);
|
|
}
|
|
if (!empty($tags)) {
|
|
$refreshParams['tag'] = implode(',', $tags);
|
|
}
|
|
|
|
return array(
|
|
'code' => 200,
|
|
'message' => 'success',
|
|
'data' => array(
|
|
'recipes' => $recipes,
|
|
'total_matched' => $totalMatched,
|
|
'returned_count' => count($recipes),
|
|
'filters_applied' => array(
|
|
'category' => $categories,
|
|
'tag' => $tags
|
|
),
|
|
'can_refresh' => $totalMatched > $count,
|
|
'refresh_url' => '?' . http_build_query($refreshParams)
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* 获取菜谱详情
|
|
* @return array
|
|
*/
|
|
function get_recipe_detail() {
|
|
global $zbp, $params;
|
|
|
|
$id = isset($params['id']) ? (int) $params['id'] : 0;
|
|
$title = isset($params['title']) ? trim($params['title']) : '';
|
|
$code = isset($params['code']) ? trim($params['code']) : '';
|
|
$fuzzy = isset($params['fuzzy']) ? (int) $params['fuzzy'] : 0;
|
|
|
|
if ($id <= 0 && empty($title) && empty($code)) {
|
|
return array(
|
|
'code' => 400,
|
|
'message' => '请提供 id、title 或 code 参数',
|
|
'data' => null
|
|
);
|
|
}
|
|
|
|
$tablePost = $zbp->db->dbpre . 'post';
|
|
$tableCategory = $zbp->db->dbpre . 'category';
|
|
$tableTag = $zbp->db->dbpre . 'tag';
|
|
$tablePostStat = $zbp->db->dbpre . 'post_stat';
|
|
$tableRecipeIngredient = $zbp->db->dbpre . 'recipe_ingredient';
|
|
$tableIngredientDetail = $zbp->db->dbpre . 'ingredient_detail';
|
|
$tableRecipeNutrition = $zbp->db->dbpre . 'recipe_nutrition';
|
|
$tableRecipeIdMap = $zbp->db->dbpre . 'recipe_id_map';
|
|
|
|
$whereClauses = array("p.log_Type = 0", "p.log_Status = 0");
|
|
|
|
if ($id > 0) {
|
|
$whereClauses[] = "p.log_ID = $id";
|
|
} elseif (!empty($code)) {
|
|
$codeId = (int) str_replace('CP', '', $code);
|
|
$whereClauses[] = "p.log_ID = $codeId";
|
|
} elseif (!empty($title)) {
|
|
$escapedTitle = $zbp->db->EscapeString($title);
|
|
if ($fuzzy === 1) {
|
|
$whereClauses[] = "p.log_Title LIKE '%$escapedTitle%'";
|
|
} else {
|
|
$whereClauses[] = "p.log_Title = '$escapedTitle'";
|
|
}
|
|
}
|
|
|
|
$whereSql = implode(' AND ', $whereClauses);
|
|
|
|
$sql = "SELECT p.log_ID, p.log_Title, p.log_Content, p.log_Intro, p.log_CateID,
|
|
p.log_PostTime, p.log_ViewNums, p.log_Tag, p.log_AuthorID,
|
|
c.cate_Name, c.cate_ParentID,
|
|
COALESCE(s.like_nums, 0) as like_nums,
|
|
COALESCE(s.rate_nums, 0) as rate_nums,
|
|
COALESCE(s.rate_score, 0) as rate_score
|
|
FROM $tablePost p
|
|
LEFT JOIN $tableCategory c ON p.log_CateID = c.cate_ID
|
|
LEFT JOIN $tablePostStat s ON p.log_ID = s.log_id
|
|
WHERE $whereSql
|
|
LIMIT 1";
|
|
|
|
$results = $zbp->db->Query($sql);
|
|
|
|
if (empty($results)) {
|
|
return array(
|
|
'code' => 404,
|
|
'message' => '菜谱不存在',
|
|
'data' => null
|
|
);
|
|
}
|
|
|
|
$row = $results[0];
|
|
$recipeId = (int) $row['log_ID'];
|
|
|
|
$picId = null;
|
|
$idMapSql = "SELECT old_id FROM $tableRecipeIdMap WHERE new_log_id = $recipeId LIMIT 1";
|
|
$idMapResult = $zbp->db->Query($idMapSql);
|
|
if (!empty($idMapResult)) {
|
|
$picId = (int) $idMapResult[0]['old_id'];
|
|
}
|
|
|
|
$tagIds = array_filter(array_map('intval', explode(',', $row['log_Tag'] ?? '')));
|
|
$tags = array();
|
|
if (!empty($tagIds)) {
|
|
$tagIdList = implode(',', $tagIds);
|
|
$tagSql = "SELECT tag_ID, tag_Name FROM $tableTag WHERE tag_ID IN ($tagIdList)";
|
|
$tagResults = $zbp->db->Query($tagSql);
|
|
foreach ($tagResults as $tagRow) {
|
|
$tags[] = array(
|
|
'id' => (int) $tagRow['tag_ID'],
|
|
'name' => $tagRow['tag_Name']
|
|
);
|
|
}
|
|
}
|
|
|
|
$parentCategory = null;
|
|
$parentId = (int) ($row['cate_ParentID'] ?? 0);
|
|
if ($parentId > 0) {
|
|
$parentSql = "SELECT cate_ID, cate_Name FROM $tableCategory WHERE cate_ID = $parentId";
|
|
$parentResult = $zbp->db->Query($parentSql);
|
|
if (!empty($parentResult)) {
|
|
$parentCategory = array(
|
|
'id' => (int) $parentResult[0]['cate_ID'],
|
|
'name' => $parentResult[0]['cate_Name']
|
|
);
|
|
}
|
|
}
|
|
|
|
$ingredientSql = "SELECT ri.name as ingredient_name, ri.amount, ri.type,
|
|
id.ingredient_id, id.alias, id.suitable_crowd, id.unsuitable_crowd,
|
|
id.intro as ingredient_intro, id.efficacy, id.cooking_tips,
|
|
id.nutrition as ingredient_nutrition, id.allergen_type,
|
|
id.category_names
|
|
FROM $tableRecipeIngredient ri
|
|
LEFT JOIN $tableIngredientDetail id ON ri.name = id.name
|
|
WHERE ri.log_id = $recipeId
|
|
ORDER BY ri.sort ASC";
|
|
$ingredientResults = $zbp->db->Query($ingredientSql);
|
|
$ingredients = array(
|
|
'main' => array(),
|
|
'auxiliary' => array(),
|
|
'seasoning' => array()
|
|
);
|
|
foreach ($ingredientResults as $ingRow) {
|
|
$type = $ingRow['type'] ?? 'main';
|
|
$ingredientDetail = array(
|
|
'name' => $ingRow['ingredient_name'],
|
|
'amount' => $ingRow['amount'] ?? ''
|
|
);
|
|
|
|
if (!empty($ingRow['ingredient_id'])) {
|
|
$ingredientDetail['detail'] = array(
|
|
'id' => (int) $ingRow['ingredient_id'],
|
|
'alias' => json_decode($ingRow['alias'] ?? '[]', true),
|
|
'suitable_crowd' => json_decode($ingRow['suitable_crowd'] ?? '[]', true),
|
|
'unsuitable_crowd' => json_decode($ingRow['unsuitable_crowd'] ?? '[]', true),
|
|
'intro' => $ingRow['ingredient_intro'] ?? '',
|
|
'efficacy' => $ingRow['efficacy'] ?? '',
|
|
'cooking_tips' => $ingRow['cooking_tips'] ?? '',
|
|
'nutrition' => json_decode($ingRow['ingredient_nutrition'] ?? '[]', true),
|
|
'allergen_type' => json_decode($ingRow['allergen_type'] ?? '[]', true),
|
|
'category_names' => json_decode($ingRow['category_names'] ?? '[]', true)
|
|
);
|
|
}
|
|
|
|
$ingredients[$type][] = $ingredientDetail;
|
|
}
|
|
|
|
$nutrition = array(
|
|
'calories' => null,
|
|
'protein' => null,
|
|
'fat' => null,
|
|
'carbohydrate' => null,
|
|
'fiber' => null,
|
|
'sodium' => null
|
|
);
|
|
|
|
$nutritionSql = "SELECT * FROM $tableRecipeNutrition WHERE log_id = $recipeId LIMIT 1";
|
|
$nutritionResult = $zbp->db->Query($nutritionSql);
|
|
if (!empty($nutritionResult)) {
|
|
$nutRow = $nutritionResult[0];
|
|
$nutrition = array(
|
|
'calories' => isset($nutRow['calories']) ? (float) $nutRow['calories'] : null,
|
|
'protein' => isset($nutRow['protein']) ? (float) $nutRow['protein'] : null,
|
|
'fat' => isset($nutRow['fat']) ? (float) $nutRow['fat'] : null,
|
|
'carbohydrate' => isset($nutRow['carbohydrate']) ? (float) $nutRow['carbohydrate'] : null,
|
|
'fiber' => isset($nutRow['fiber']) ? (float) $nutRow['fiber'] : null,
|
|
'sodium' => isset($nutRow['sodium']) ? (float) $nutRow['sodium'] : null
|
|
);
|
|
}
|
|
|
|
$cover = '';
|
|
if (preg_match('/<img[^>]+src=["\']([^"\']+)["\']/i', $row['log_Content'] ?? '', $matches)) {
|
|
$cover = $matches[1];
|
|
}
|
|
|
|
$result = array(
|
|
'code' => 200,
|
|
'message' => 'success',
|
|
'data' => array(
|
|
'id' => $recipeId,
|
|
'code' => 'CP' . str_pad($recipeId, 6, '0', STR_PAD_LEFT),
|
|
'pic_id' => $picId,
|
|
'title' => $row['log_Title'],
|
|
'cover' => $cover,
|
|
'intro' => mb_substr(strip_tags($row['log_Intro'] ?? ''), 0, 200),
|
|
'content' => $row['log_Content'] ?? '',
|
|
'category' => array(
|
|
'id' => (int) ($row['log_CateID'] ?? 0),
|
|
'name' => $row['cate_Name'] ?? '',
|
|
'parent' => $parentCategory
|
|
),
|
|
'tags' => $tags,
|
|
'ingredients' => $ingredients,
|
|
'nutrition' => $nutrition,
|
|
'statistics' => array(
|
|
'view' => (int) ($row['log_ViewNums'] ?? 0),
|
|
'like' => (int) ($row['like_nums'] ?? 0),
|
|
'rate_count' => (int) ($row['rate_nums'] ?? 0),
|
|
'rate_score' => (float) ($row['rate_score'] ?? 0)
|
|
),
|
|
'rating' => ApiResponse::formatRating(
|
|
(float) ($row['rate_score'] ?? 0),
|
|
(int) ($row['rate_nums'] ?? 0)
|
|
),
|
|
'author' => array(
|
|
'id' => (int) ($row['log_AuthorID'] ?? 0),
|
|
'name' => '管理员'
|
|
),
|
|
'publish_time' => $row['log_PostTime'] ?? '',
|
|
'url' => '?act=detail&id=' . $recipeId
|
|
)
|
|
);
|
|
|
|
return $result;
|
|
}
|