better-staridc-MNBT
1<?php
2/**
3 * official_site 插件 - 主入口
4 *
5 * 功能:企业官网内容管理(产品展示、新闻资讯、联系留言)
6 * 架构:
7 * - 前台:通过 P2 路由注册 /site/api/* 数据接口,供 home SPA「产品/新闻/联系」页面使用
8 * - 管理员端:通过 mnbt_register_page('admin', ...) 注册到 admin/plugin.php,侧边栏「官网内容」菜单
9 * 能力探测:启用后 home 引擎注入 has_site=true,自动开启「关于/产品/新闻/联系」页面与导航
10 */
11
12if (!defined('IN_CRONLITE')) {
13 exit;
14}
15
16require_once __DIR__ . '/lib/site.php';
17
18mnbt_plugin_register('official_site', [
19 'name' => '官网内容',
20 'description' => '企业官网内容管理:产品展示、新闻资讯、联系留言',
21]);
22
23/* ============================================================
24 * 前台 API 路由(home SPA 数据接口)
25 * ============================================================ */
26
27// 产品列表(支持 ?category= 筛选,返回分类定义)
28mnbt_register_route('GET', '/site/api/products', function ($params, $ctx) {
29 $category = isset($_GET['category']) ? trim($_GET['category']) : '';
30 $rows = site_product_list('active', $category);
31 $cat = site_product_categories();
32 $products = [];
33 foreach ($rows as $p) {
34 $products[] = [
35 'id' => (int)$p['id'],
36 'name' => (string)$p['name'],
37 'category' => (string)$p['category'],
38 'category_name' => (string)($cat[$p['category']] ?? $p['category']),
39 'description' => (string)$p['description'],
40 'features' => $p['features_list'],
41 'image' => (string)($p['image'] ?? ''),
42 'link' => (string)($p['link'] ?? ''),
43 ];
44 }
45 $cats = [];
46 foreach ($cat as $k => $v) {
47 $cats[] = ['id' => $k, 'name' => $v];
48 }
49 site_json('ok', ['products' => $products, 'categories' => $cats]);
50});
51
52// 产品详情
53mnbt_register_route('GET', '/site/api/products/{product_id}', function ($params, $ctx) {
54 $id = (int)($params['product_id'] ?? 0);
55 $p = site_product_get($id);
56 if (!$p || $p['status'] !== 'active') {
57 site_json('产品不存在');
58 return;
59 }
60 $cat = site_product_categories();
61 site_json('ok', ['product' => [
62 'id' => (int)$p['id'],
63 'name' => (string)$p['name'],
64 'category' => (string)$p['category'],
65 'category_name' => (string)($cat[$p['category']] ?? $p['category']),
66 'description' => (string)$p['description'],
67 'features' => $p['features_list'],
68 'image' => (string)($p['image'] ?? ''),
69 'link' => (string)($p['link'] ?? ''),
70 'created_at' => (string)($p['created_at'] ?? ''),
71 ]]);
72});
73
74// 新闻列表(分页 + 分类,返回分类统计)
75mnbt_register_route('GET', '/site/api/news', function ($params, $ctx) {
76 $page = isset($_GET['page']) ? max(1, (int)$_GET['page']) : 1;
77 $per = isset($_GET['per_page']) ? max(1, min(50, (int)$_GET['per_page'])) : 6;
78 $category = isset($_GET['category']) ? trim($_GET['category']) : '';
79 $data = site_news_list($page, $per, $category);
80 $list = [];
81 foreach ($data['list'] as $n) {
82 $list[] = [
83 'id' => (int)$n['id'],
84 'title' => (string)$n['title'],
85 'category' => (string)$n['category'],
86 'content' => (string)$n['content'],
87 'views' => (int)$n['views'],
88 'created_at' => (string)$n['created_at'],
89 ];
90 }
91 site_json('ok', [
92 'news' => $list,
93 'total' => (int)$data['total'],
94 'page' => $page,
95 'per_page' => $per,
96 'categories' => site_news_categories(),
97 ]);
98});
99
100// 热门新闻(静态段需注册在 /news/{news_id} 之前,避免被参数路由吞掉)
101mnbt_register_route('GET', '/site/api/news/popular', function ($params, $ctx) {
102 $rows = site_news_popular(4);
103 $list = [];
104 foreach ($rows as $n) {
105 $list[] = [
106 'id' => (int)$n['id'],
107 'title' => (string)$n['title'],
108 'views' => (int)$n['views'],
109 'created_at' => (string)$n['created_at'],
110 ];
111 }
112 site_json('ok', ['popular' => $list]);
113});
114
115// 新闻详情(累计浏览量)
116mnbt_register_route('GET', '/site/api/news/{news_id}', function ($params, $ctx) {
117 $id = (int)($params['news_id'] ?? 0);
118 $n = site_news_get($id, true);
119 if (!$n || $n['status'] !== 'active') {
120 site_json('新闻不存在');
121 return;
122 }
123 site_json('ok', ['news' => [
124 'id' => (int)$n['id'],
125 'title' => (string)$n['title'],
126 'category' => (string)$n['category'],
127 'content' => (string)$n['content'],
128 'views' => (int)$n['views'],
129 'created_at' => (string)$n['created_at'],
130 ]]);
131});
132
133// 提交留言
134mnbt_register_route('POST', '/site/api/contact', function ($params, $ctx) {
135 $r = site_message_add([
136 'name' => $_POST['name'] ?? '',
137 'email' => $_POST['email'] ?? '',
138 'phone' => $_POST['phone'] ?? '',
139 'message' => $_POST['message'] ?? '',
140 ]);
141 if ($r !== true) {
142 site_json($r);
143 return;
144 }
145 site_json('ok');
146});
147
148/* ============================================================
149 * 管理员端页面注册
150 * ============================================================ */
151
152mnbt_register_page('admin', 'site_products', 'views/admin/products.php', '产品管理');
153mnbt_register_page('admin', 'site_news', 'views/admin/news.php', '新闻管理');
154mnbt_register_page('admin', 'site_messages', 'views/admin/messages.php', '留言管理');
155
156// 侧边栏菜单
157mnbt_register_menu('admin', [
158 'title' => '官网内容',
159 'icon' => 'mdi-web',
160 'order' => 55,
161 'children' => [
162 ['title' => '产品管理', 'page' => 'site_products', 'icon' => 'mdi-package-variant', 'multitabs' => true],
163 ['title' => '新闻管理', 'page' => 'site_news', 'icon' => 'mdi-newspaper', 'multitabs' => true],
164 ['title' => '留言管理', 'page' => 'site_messages', 'icon' => 'mdi-email-open', 'multitabs' => true],
165 ],
166]);