diff --git a/docs/拼接接口路径.md b/docs/拼接接口路径.md new file mode 100644 index 0000000..cb115ba --- /dev/null +++ b/docs/拼接接口路径.md @@ -0,0 +1,11 @@ +//拼接接口路径 +const getEnvUrl = (path: string) => { + const API_BASE_URL = import.meta.env.VITE_API_BASE_URL; + return `${API_BASE_URL}${path}`; +}; + +用例: + + + +const url = getEnvUrl('/admin/moduleCenter/modules'); diff --git a/docs/调用图片上传组件.md b/docs/调用图片上传组件.md index c955913..0db1a98 100644 --- a/docs/调用图片上传组件.md +++ b/docs/调用图片上传组件.md @@ -1,39 +1,39 @@ - -
- - - - + +
+ + + + - + + + Preview Image + -
- 建议尺寸:250px × 140px +
+ 建议尺寸:250px × 140px +
-
-
- + import { uploadFile } from '@/api/file.js'; import { ElMessage, ElUpload } from 'element-plus' diff --git a/src/api/moduleCenter.js b/src/api/moduleCenter.js new file mode 100644 index 0000000..26d6954 --- /dev/null +++ b/src/api/moduleCenter.js @@ -0,0 +1,57 @@ +import request from "@/utils/request"; + +/** + * 获取模块中心分类 + * @returns {Promise} + */ +export function getModuleCategory() { + return request({ + url: "/admin/moduleCategory", + method: "get", + }); +} + +/** + * 获取模块中心列表 + * @param {number} cid 分类id + * @returns {Promise} + */ +export function getModules(cid) { + return request({ + url: "/admin/moduleCenter/modules", + method: "get", + params: { cid } + }); +} + +/** + * 编辑模块分类 + * @param {Object} data 分类数据 + * @param {number} data.id 分类id(编辑时必填,新增时不填) + * @param {string} data.title 分类名称 + * @param {number} data.status 分类状态 + * @returns {Promise} + */ +export function editModuleCategory(data) { + return request({ + url: "/admin/moduleCenter/editCategory", + method: "post", + data + }); +} + +/** + * 编辑模块 + * @param {Object} data 模块数据 + * @param {number} data.id 模块id(编辑时必填,新增时不填) + * @param {string} data.title 模块名称 + * @param {number} data.status 模块状态 + * @returns {Promise} + */ +export function editModules(data) { + return request({ + url: "/admin/moduleCenter/editModules", + method: "post", + data + }); +} diff --git a/src/views/home/index.vue b/src/views/home/index.vue index 7556de8..b04bf5b 100644 --- a/src/views/home/index.vue +++ b/src/views/home/index.vue @@ -54,37 +54,69 @@
- -
-
-
-
- {{ module.name }} -
+ +
+
功能模块
+
+
+
+ {{ module.name }} +
+
+
+
+

{{ module.description || "暂无描述" }}

+
-
-
-

{{ module.description || "暂无描述" }}

+
+
+ + +
+
系统设置
+
+
+
+ {{ module.name }} +
+
+
+
+

{{ module.description || "暂无描述" }}

+
+
+
+
+ + +
+
未分类
+
+
+
+ {{ module.name }} +
+
+
+
+

{{ module.description || "暂无描述" }}

+
@@ -127,12 +159,25 @@ interface ModuleItem { description: string; sort: number; status: number; + type: number; + title?: string; } const router = useRouter(); const authStore = useAuthStore(); const menuStore = useMenuStore(); +// 根据type分组模块 +const basicModules = computed(() => + moduleList.value.filter((item) => item.type === 1) +); +const systemModules = computed(() => + moduleList.value.filter((item) => item.type === 2) +); +const uncategorizedModules = computed(() => + moduleList.value.filter((item) => item.type === 0) +); + const moduleList = ref([]); const refreshLoading = ref(false); @@ -231,7 +276,12 @@ async function loadModules() { const list = res.data?.list || []; moduleList.value = list .filter((item: ModuleItem) => item.status === 1 && item.is_show === 1) - .sort((a, b) => Number(a.sort) - Number(b.sort)); + .sort((a, b) => Number(a.sort) - Number(b.sort)) + .map((item: ModuleItem) => ({ + ...item, + type: item.type || 0, // 默认为0(未分类) + title: item.name // 添加title字段用于显示分类标题 + })); } } catch (error) { console.error("加载模块列表失败:", error); @@ -416,14 +466,27 @@ $text-regular: #606266; .modules-section { margin-top: 20px; + .category-section { + margin-bottom: 32px; + + .category-title { + font-size: 16px; + font-weight: 600; + color: $text-main; + margin: 0 0 20px 0; + padding-left: 4px; + border-left: 4px solid #667eea; + } + } + .module-grid { display: grid; - grid-template-columns: repeat(4, 1fr); + grid-template-columns: repeat(5, 1fr); gap: 20px; } .module-card { - height: 220px; + height: 180px; background: #fff; border-radius: 12px; padding: 30px; @@ -468,7 +531,7 @@ $text-regular: #606266; margin: 0; line-height: 1.5; display: -webkit-box; - -webkit-line-clamp: 2; + -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; } diff --git a/src/views/moduleshop/category/index.vue b/src/views/moduleshop/category/index.vue new file mode 100644 index 0000000..ee0fcab --- /dev/null +++ b/src/views/moduleshop/category/index.vue @@ -0,0 +1,313 @@ + + + + + diff --git a/src/views/moduleshop/center/index.vue b/src/views/moduleshop/center/index.vue index b5af314..39c6ef0 100644 --- a/src/views/moduleshop/center/index.vue +++ b/src/views/moduleshop/center/index.vue @@ -2,51 +2,44 @@
-
-
- {{ category.name }} +
+
+ {{ category.title }} +
-
-
+
-
- -
+ +
-

{{ module.name }}

-

{{ module.description || '暂无描述' }}

+

{{ module.title }}

+

{{ module.desc || '暂无描述' }}

- + - +
@@ -478,7 +466,7 @@ onMounted(() => { border-radius: 20px; font-size: 14px; color: var(--el-text-color-regular); - background: var(--el-fill-color-light); + background: var(--el-bg-color); cursor: pointer; transition: all 0.3s; border: 1px solid transparent; @@ -499,7 +487,7 @@ onMounted(() => { .modules-grid { display: grid; - grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); + grid-template-columns: repeat(5, 1fr); gap: 20px; .module-card { @@ -531,6 +519,12 @@ onMounted(() => { justify-content: center; position: relative; overflow: hidden; + + img{ + width: 100%; + height: 100%; + object-fit: cover; + } &::before { content: ''; @@ -539,24 +533,9 @@ onMounted(() => { right: -50%; width: 100%; height: 100%; - background: linear-gradient(135deg, rgba(255,255,255,0.3) 0%, transparent 100%); + background: linear-gradient(135deg, rgba(255, 255, 255, 0.3) 0%, transparent 100%); transform: rotate(45deg); } - - .preview-image { - width: 80px; - height: 80px; - border-radius: 16px; - background: #fff; - display: flex; - align-items: center; - justify-content: center; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); - - .el-icon { - color: var(--el-color-primary); - } - } } .module-content { @@ -589,7 +568,7 @@ onMounted(() => { padding-top: 16px; border-top: 1px solid var(--el-border-color-lighter); - .module-company, + .module-category, .module-downloads { display: flex; align-items: center; @@ -612,6 +591,11 @@ onMounted(() => { align-items: center; gap: 8px; + .action-item { + width: 16px; + height: 16px; + } + .el-button { color: var(--el-text-color-regular); background: rgba(255, 255, 255, 0.9); @@ -634,14 +618,63 @@ onMounted(() => { padding: 80px 20px; text-align: center; } + + .uploads { + display: flex; + flex-direction: column; + } + + .upload-tip { + font-size: 12px; + color: #999; + margin-top: 8px; + } } -@media (max-width: 768px) { +@media (max-width: 1400px) { .modules-container { .modules-grid { - grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); - gap: 16px; + grid-template-columns: repeat(4, 1fr); } } } + +@media (max-width: 1200px) { + .modules-container { + .modules-grid { + grid-template-columns: repeat(3, 1fr); + } + } +} + +@media (max-width: 992px) { + .modules-container { + .modules-grid { + grid-template-columns: repeat(2, 1fr); + } + } +} + +@media (max-width: 576px) { + .modules-container { + .modules-grid { + grid-template-columns: 1fr; + } + } +} + +.uploads{ + display: flex; + flex-direction: column; +} +.upload-tip { + font-size: 12px; + color: #999; +} + +:deep(.el-upload-list__item-thumbnail) { + width: 100%; + height: 100%; + object-fit: cover; +} diff --git a/src/views/moduleshop/publish/index.vue b/src/views/moduleshop/publish/index.vue index 803a68e..055bf79 100644 --- a/src/views/moduleshop/publish/index.vue +++ b/src/views/moduleshop/publish/index.vue @@ -5,7 +5,7 @@
发布管理 - 新增发布 + 新增模块
@@ -17,16 +17,9 @@ border > - + - - - - + +