diff --git a/js/index.js b/js/index.js
index 2b97141..983ba79 100644
--- a/js/index.js
+++ b/js/index.js
@@ -32,12 +32,71 @@ $(function () {
}
}
isRecommend();
- // 设置首页函数
- function setIndexData() {
- const commentObj = JSON.parse(sessionStorage.commentData);
- if (commentObj.honor.length > 0) {
- commentObj.honor.forEach((item) => {
- $("#certBox").append(`
+ let bannerSwiper = null;
+ const initBannerSwiper = () => {
+ if (bannerSwiper) {
+ bannerSwiper.destroy(true, true);
+ }
+ bannerSwiper = new Swiper(".swiper", {
+ loop: true,
+ autoplay: true,
+ pagination: {
+ el: ".swiper-pagination",
+ clickable: true,
+ },
+ });
+ };
+
+ const renderBannerSlides = (list = []) => {
+ const wrapper = document.getElementById("bannerWrapper");
+ if (!wrapper) {
+ return;
+ }
+ if (!Array.isArray(list) || list.length === 0) {
+ initBannerSwiper();
+ return;
+ }
+ wrapper.innerHTML = "";
+ list.forEach((item) => {
+ const slide = document.createElement("div");
+ slide.className = "swiper-slide";
+ const title = item.title ? `
${item.title}
` : "";
+ const desc = item.description
+ ? `
${item.description}
`
+ : "";
+ let buttonHtml = "";
+ if (item.button_text) {
+ const link = item.button_link || "javascript:;";
+ const target = item.button_blank ? "_blank" : "_self";
+ buttonHtml = `
${item.button_text}`;
+ }
+ const targetAttr = item.blank ? "_blank" : "_self";
+ const imgHtml = `

`;
+ const mediaBlock = item.url
+ ? `
${imgHtml}`
+ : imgHtml;
+ const contentBlock =
+ title || desc || buttonHtml
+ ? `
${title}${desc}${buttonHtml}
`
+ : "";
+ slide.innerHTML = `
+ ${mediaBlock}
+ ${contentBlock}
+ `;
+ wrapper.appendChild(slide);
+ });
+ initBannerSwiper();
+ };
+
+ // 设置首页函数
+ function setIndexData() {
+ const commentObj = JSON.parse(sessionStorage.commentData);
+ renderBannerSlides(commentObj.banner);
+ if (commentObj.honor.length > 0) {
+ commentObj.honor.forEach((item) => {
+ $("#certBox").append(`
${item.name}
`);
@@ -106,15 +165,7 @@ $(function () {
viewer.show();
});
- const mySwiper = new Swiper(".swiper", {
- loop: true, // 循环模式选项
- autoplay: true,
- // 如果需要分页器
- pagination: {
- el: ".swiper-pagination",
- clickable: true,
- },
- });
+ initBannerSwiper();
function formateTimeFun(time) {
const date = new Date(time * 1000);
Y = date.getFullYear() + "-";
diff --git a/plugins/addon/theme_configurator/README.md b/plugins/addon/theme_configurator/README.md
index 31b9c9f..7634860 100644
--- a/plugins/addon/theme_configurator/README.md
+++ b/plugins/addon/theme_configurator/README.md
@@ -3,7 +3,7 @@
此插件演示如何通过后台插件的方式为 BlackFruit-UI 主题提供可配置能力,支持设置导航、页脚、站点信息、SEO、首页轮播以及右侧浮窗,并提供 `/console/v1/theme/config` 接口与前端联动。
## 功能
-- 后台界面(`template/admin/index.php`)以 JSON 的形式集中维护所有主题参数;
+- 后台界面(`template/admin/index.html`)以 JSON 的形式集中维护所有主题参数;
- 接口 `GET/POST /{DIR_ADMIN}/v1/theme/config` 提供配置读取与保存;
- 前台接口 `GET /console/v1/theme/config` 输出与 `/console/v1/common` 相同结构的数据,BlackFruit-UI 可以直接接入;
- 插件安装时创建 `addon_theme_configurator` 表并写入默认配置。
@@ -16,7 +16,7 @@ plugins/addon/theme_configurator
│ ├── ThemeController.php # 后台 API
│ └── clientarea/ThemeController.php # 前台 API
├── model/ThemeConfigModel.php # 主题配置模型
-├── template/admin/index.php # 后台可视化页面
+├── template/admin/index.html # 后台可视化页面
├── route.php # 自定义路由定义
├── sidebar*.php # 前后台导航
├── auth.php # 权限配置
@@ -26,5 +26,22 @@ plugins/addon/theme_configurator
## 使用步骤
1. 将目录复制到业务系统的 `public/plugins/addon` 下;
2. 在后台启用插件,安装脚本会自动创建 `addon_theme_configurator` 表;
-3. 进入“插件 > 主题配置”页,按 JSON 结构维护导航、SEO、轮播、侧边栏等;
+3. 进入“插件 > 主题配置”页(`index.html`),按 JSON 结构维护导航、SEO、轮播、侧边栏等;
4. 前端 BlackFruit-UI 请求 `/console/v1/theme/config` 以获取运行时配置。若需要兼容现有 `/console/v1/common`,可在 Nginx 或网关层做转发。
+
+### banner 字段示例
+```json
+"banner": [
+ {
+ "title": "中小企业的云计算底座",
+ "description": "自定义文案",
+ "img": "/upload/banner-1.png",
+ "url": "/cloud.html",
+ "blank": false,
+ "button_text": "立即查看",
+ "button_link": "/cloud.html",
+ "button_blank": false
+ }
+]
+```
+BlackFruit-UI 会在首页读取 `banner` 数组动态渲染轮播图,`url/blank` 控制整张 Banner 的跳转,`button_*` 控制右下角按钮。