From a4f7a9776382eb628bdb9cbb8c6acc52e8406dbe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=9D=8E=E5=BF=97=E5=BC=BA?= <357099073@qq.com>
Date: Thu, 20 Aug 2026 17:47:47 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96backend=E4=BA=A7=E5=93=81?=
=?UTF-8?q?=E5=92=8C=E8=A7=A3=E5=86=B3=E6=96=B9=E6=A1=88?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
backend/src/components/CommonAside.vue | 8 +++
backend/src/router/dynamicRoutes.js | 12 ++--
backend/src/router/index.js | 6 ++
.../cms/article/index/components/preview.vue | 14 ++++
.../views/apps/cms/article/index/index.vue | 4 +-
.../cms/product/index/components/edit.vue | 36 ++++++++--
.../cms/solution/index/components/edit.vue | 65 ++++++++++++++-----
.../views/apps/cms/solution/index/index.vue | 44 ++++++++-----
backend/src/views/components/UmoEditor.vue | 33 ++++++++--
backend/src/views/home/index.vue | 15 +++--
go/controllers/backend_solution.go | 16 +++--
go/models/backend_menu_front.go | 6 --
go/models/cms_solution.go | 4 ++
go/models/init.go | 5 ++
14 files changed, 201 insertions(+), 67 deletions(-)
diff --git a/backend/src/components/CommonAside.vue b/backend/src/components/CommonAside.vue
index ddb0574..b895a77 100644
--- a/backend/src/components/CommonAside.vue
+++ b/backend/src/components/CommonAside.vue
@@ -296,6 +296,14 @@ const fixedCmsMenu = {
icon: "Document",
order: -200,
children: [
+ {
+ id: -2001,
+ path: "/apps/cms/analytics/content",
+ title: "内容统计",
+ icon: "DataAnalysis",
+ order: 0,
+ children: []
+ },
{
id: -201,
path: "/apps/cms/article",
diff --git a/backend/src/router/dynamicRoutes.js b/backend/src/router/dynamicRoutes.js
index d1fb33c..24c0c48 100644
--- a/backend/src/router/dynamicRoutes.js
+++ b/backend/src/router/dynamicRoutes.js
@@ -160,11 +160,13 @@ export function convertMenusToRoutes(menus, parentPath = '') {
} else if (hasChildren) {
route.component = () => import('@/views/layouts/EmptyLayout.vue');
route.children = convertMenusToRoutes(menu.children, fullPath);
- const firstChild = menu.children[0];
- if (firstChild && firstChild.path) {
- const childFullPath = firstChild.path.startsWith('/')
- ? firstChild.path
- : `${fullPath}/${firstChild.path}`;
+ const defaultChild = menu.children.find((child) =>
+ child.path === '/apps/cms/analytics/content' || child.path === 'analytics/content'
+ ) || menu.children[0];
+ if (defaultChild && defaultChild.path) {
+ const childFullPath = defaultChild.path.startsWith('/')
+ ? defaultChild.path
+ : `${fullPath}/${defaultChild.path}`;
route.redirect = childFullPath;
}
} else {
diff --git a/backend/src/router/index.js b/backend/src/router/index.js
index 113f0ed..1e23ac2 100644
--- a/backend/src/router/index.js
+++ b/backend/src/router/index.js
@@ -12,6 +12,12 @@ const staticMainChildren = [
},
// CMS 文章/产品/解决方案是系统内置功能,不依赖数据库菜单配置。
// 统一结构:index 为列表页,type 为分类页。
+ {
+ path: "/apps/cms/analytics/content",
+ name: "CmsContentAnalytics",
+ component: () => import("@/views/apps/cms/analytics/content/index.vue"),
+ meta: { requiresAuth: true, title: "内容统计", modulePath: "/apps/cms" }
+ },
{
path: "/apps/cms/article",
name: "CmsArticles",
diff --git a/backend/src/views/apps/cms/article/index/components/preview.vue b/backend/src/views/apps/cms/article/index/components/preview.vue
index 7747110..ef5977a 100644
--- a/backend/src/views/apps/cms/article/index/components/preview.vue
+++ b/backend/src/views/apps/cms/article/index/components/preview.vue
@@ -98,6 +98,20 @@ const getCategoryName = (cate) => {
return category?.name || "无分类";
};
+// 格式化日期
+const formatDate = (date: string | number | Date) => {
+ if (!date) return "-";
+ const d = new Date(date);
+ if (isNaN(d.getTime())) return String(date);
+ const year = d.getFullYear();
+ const month = String(d.getMonth() + 1).padStart(2, "0");
+ const day = String(d.getDate()).padStart(2, "0");
+ const hours = String(d.getHours()).padStart(2, "0");
+ const minutes = String(d.getMinutes()).padStart(2, "0");
+ const seconds = String(d.getSeconds()).padStart(2, "0");
+ return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
+};
+
const emit = defineEmits(["update:modelValue"]);
const visible = ref(false);
diff --git a/backend/src/views/apps/cms/article/index/index.vue b/backend/src/views/apps/cms/article/index/index.vue
index d99c0ff..20665aa 100644
--- a/backend/src/views/apps/cms/article/index/index.vue
+++ b/backend/src/views/apps/cms/article/index/index.vue
@@ -213,8 +213,8 @@
import { ref, onMounted } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { Search } from "@element-plus/icons-vue";
-import Edit from "./index/components/edit.vue";
-import Preview from "./index/components/preview.vue";
+import Edit from "./components/edit.vue";
+import Preview from "./components/preview.vue";
import { useAuthStore } from "@/stores/auth";
import {
listArticles,
diff --git a/backend/src/views/apps/cms/product/index/components/edit.vue b/backend/src/views/apps/cms/product/index/components/edit.vue
index 17ea62d..7e33b81 100644
--- a/backend/src/views/apps/cms/product/index/components/edit.vue
+++ b/backend/src/views/apps/cms/product/index/components/edit.vue
@@ -1,8 +1,9 @@
-