weixin_52219567 1 день назад
Родитель
Сommit
b4d1668cf4

+ 8 - 0
src/api/pmsProduct/program/index.ts

@@ -16,6 +16,14 @@ export const listProgram = (query?: ProgramQuery): AxiosPromise<ProgramVO[]> =>
   });
   });
 };
 };
 
 
+export const programList = (query?: ProgramQuery): AxiosPromise<ProgramVO[]> => {
+  return request({
+    url: '/product/program/list',
+    method: 'get',
+    params: query
+  });
+};
+
 /**
 /**
  * 查询产品解决方案/项目方案详细
  * 查询产品解决方案/项目方案详细
  * @param id
  * @param id

+ 702 - 1103
src/components/LinkSelector/index.vue

@@ -1,308 +1,447 @@
 <template>
 <template>
-  <el-dialog v-model="dialogVisible" title="选择链接" width="65%" @close="handleClose">
-    <div class="link-selector-container">
-      <!-- 左侧树状结构导航 -->
-      <div class="tree-container">
-        <el-tree ref="treeRef" :data="treeData" node-key="id" :props="defaultProps" @node-click="handleNodeClick" default-expand-all></el-tree>
-      </div>
-
-      <!-- 右侧链接内容 -->
-      <div class="links-container">
-        <div v-if="selectedCategory" class="category-title">{{ selectedCategory.title || selectedCategory.name }}</div>
-        <div v-else class="category-title">基础链接</div>
-
-        <!-- 链接区域 -->
-        <div class="link-list-container">
-          <!-- 商品链接选择区域 -->
-          <div v-if="isProductCategoryComputed" class="product-selection-container">
-            <!-- 搜索框 -->
-            <div class="product-search">
-              <el-input v-model="productSearchKeyword" placeholder="请输入商品名称关键词" clearable @keyup.enter="handleProductSearch" />
-              <el-button type="primary" @click="handleProductSearch">搜索</el-button>
+  <div>
+    <el-dialog v-model="showDialog" title="选择链接" width="1000">
+      <div class="dialog-bos">
+        <div class="menu-container">
+          <el-menu @select="onMenu" style="height: 100%" :default-openeds="defaultOpeneds" :default-active="defaultActive" v-if="menuData.length > 0">
+            <template v-for="(item1, index1) in menuData" :key="index1">
+              <el-sub-menu :index="index1 + ''" v-if="item1.children && item1.children.length > 0">
+                <template #title>{{ item1.name }}</template>
+                <el-menu-item v-for="(item2, index2) in item1.children" :key="index2" :index="index1 + '-' + index2">{{ item2.name }}</el-menu-item>
+              </el-sub-menu>
+              <el-menu-item v-else :index="index1 + ''">{{ item1.name }}</el-menu-item>
+            </template>
+          </el-menu>
+        </div>
+        <div class="dialog-box">
+          <template v-if="boxShow1">
+            <div v-for="(item1, index1) in boxData" :key="index1">
+              <h5 class="button-title">
+                <div class="title">{{ item1.name }}</div>
+                <div v-if="index1 == 0">
+                  <span class="mr-[5px]">是否新窗口打开</span>
+                  <el-switch v-model="switchVal" />
+                </div>
+              </h5>
+              <div class="button-container">
+                <el-button
+                  @click="onSelected(item2)"
+                  :type="item2.url == selected ? 'primary' : ''"
+                  v-for="(item2, index2) in item1.children"
+                  :key="index2"
+                  >{{ item2.name }}</el-button
+                >
+              </div>
             </div>
             </div>
-
-            <!-- 商品列表 -->
-            <div class="product-list">
+          </template>
+          <template v-else>
+            <div v-if="boxpageKey == 'goodsClassify'">
+              <div>
+                <span class="mr-[5px]">是否新窗口打开</span>
+                <el-switch v-model="switchVal" />
+              </div>
               <el-table
               <el-table
-                :data="productList"
-                :style="{ width: '100%' }"
-                :row-class-name="({ row }) => (selectedProduct?.id === row.id ? 'product-row-active' : '')"
-                @row-click="handleProductSelect"
-                class="custom-product-table"
+                style="width: 100%"
+                height="546px"
+                v-loading="loading1"
+                :data="tableData1"
+                row-key="id"
+                border
+                lazy
+                :load="loadChildren"
+                :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
               >
               >
-                <el-table-column width="80">
+                <el-table-column width="120" align="center">
                   <template #default="{ row }">
                   <template #default="{ row }">
-                    <el-radio :model-value="selectedProduct?.id" :label="row.id" @change="() => handleProductSelect(row)" />
+                    <el-checkbox v-model="tableId1" :true-value="row.id" @change="handleCheckboxChange(row)" />
                   </template>
                   </template>
                 </el-table-column>
                 </el-table-column>
-                <el-table-column label="ID" prop="id" width="180" />
-                <el-table-column label="图片" width="120">
-                  <template #default="{ row }">
-                    <el-image
-                      :src="row.image || ''"
-                      style="width: 80px; height: 60px; object-fit: cover; display: block"
-                      :preview-src-list="row.image ? [row.image] : []"
-                    >
-                      <template #error>
-                        <div class="image-slot">
-                          <el-icon><Picture /></el-icon>
-                        </div>
-                      </template>
-                    </el-image>
+                <el-table-column prop="categoryName" label="分类名称" minWidth="260"></el-table-column>
+                <el-table-column prop="classLevel" align="center" label="分类级别" width="150">
+                  <template #default="scope">
+                    <span>{{ scope.row.classLevel }}级</span>
                   </template>
                   </template>
                 </el-table-column>
                 </el-table-column>
-                <el-table-column prop="name" label="商品名称">
-                  <template #default="{ row }">
-                    <div class="product-name">{{ row.name }}</div>
+                <el-table-column prop="platform" align="center" label="平台" width="150">
+                  <template #default="scope">
+                    <span>{{ scope.row.platform === 0 ? '工业品' : scope.row.platform === 1 ? 'PC端' : '未知' }}</span>
                   </template>
                   </template>
                 </el-table-column>
                 </el-table-column>
               </el-table>
               </el-table>
             </div>
             </div>
-          </div>
-
-          <!-- 文章链接选择区域 -->
-          <div v-else-if="isArticleCategoryComputed" class="article-selection-container">
-            <!-- 搜索框 -->
-            <div class="product-search">
-              <el-input v-model="articleSearchKeyword" placeholder="请输入文章标题关键词" clearable @keyup.enter="handleArticleSearch" />
-              <el-button type="primary" @click="handleArticleSearch">搜索</el-button>
-            </div>
-
-            <!-- 文章列表 -->
-            <div class="article-list">
-              <el-table
-                :data="articleList"
-                :style="{ width: '100%' }"
-                :row-class-name="({ row }) => (selectedArticle?.id === row.id ? 'article-row-active' : '')"
-                @row-click="handleArticleSelect"
-                class="custom-article-table"
-              >
-                <el-table-column width="80">
+            <!-- 商品 -->
+            <div v-if="boxpageKey == 'goodsItem'">
+              <div class="flex justify-between">
+                <el-input v-model="queryParams2.itemName" placeholder="请输入商品名称" clearable style="width: 300px; margin-bottom: 10px">
+                  <template #append>
+                    <el-button :icon="Search" @click="handleQuery2" />
+                  </template>
+                </el-input>
+                <div>
+                  <span class="mr-[5px]">是否新窗口打开</span>
+                  <el-switch v-model="switchVal" />
+                </div>
+              </div>
+              <el-table height="480" ref="multipleTableRef" v-loading="loading2" :data="tableData2" border>
+                <el-table-column width="80" align="center">
                   <template #default="{ row }">
                   <template #default="{ row }">
-                    <el-radio :model-value="selectedArticle?.id" :label="row.id" @change="() => handleArticleSelect(row)" />
+                    <el-checkbox v-model="tableId2" :true-value="row.productNo" />
                   </template>
                   </template>
                 </el-table-column>
                 </el-table-column>
-                <el-table-column label="ID" prop="id" width="180" />
-                <el-table-column prop="title" label="文章标题">
-                  <template #default="{ row }">
-                    <div class="article-title">{{ row.title }}</div>
+                <el-table-column label="商品图片" align="center" prop="productImage" width="100">
+                  <template #default="scope">
+                    <image-preview :src="scope.row.productImage" :width="60" :height="60" />
+                  </template>
+                </el-table-column>
+                <el-table-column label="商品信息" align="center" minWidth="250" show-overflow-tooltip>
+                  <template #default="scope">
+                    <div class="text-left">
+                      <div>{{ scope.row.itemName }}</div>
+                      <div class="text-gray-500" style="font-size: 12px">品牌: {{ scope.row.brandName || '-' }}</div>
+                    </div>
+                  </template>
+                </el-table-column>
+                <el-table-column label="SKU价格" align="center" width="180">
+                  <template #default="scope">
+                    <div class="text-left" style="font-size: 12px">
+                      <div>
+                        <span class="text-gray-500">市场价:</span>
+                        <span class="text-red-500">¥{{ scope.row.marketPrice || '0.00' }}</span>
+                      </div>
+                      <div>
+                        <span class="text-gray-500">会员价:</span>
+                        <span class="text-red-500">¥{{ scope.row.memberPrice || '0.00' }}</span>
+                      </div>
+                      <div>
+                        <span class="text-gray-500">最低价:</span>
+                        <span class="text-red-500">¥{{ scope.row.minSellingPrice || '0.00' }}</span>
+                      </div>
+                    </div>
+                  </template>
+                </el-table-column>
+                <el-table-column label="成本情况" align="center" width="150">
+                  <template #default="scope">
+                    <div class="text-left" style="font-size: 12px">
+                      <div>
+                        <span class="text-gray-500">采购价:</span>
+                        <span>¥{{ scope.row.purchasingPrice || '0.00' }}</span>
+                      </div>
+                      <div>
+                        <span class="text-gray-500">暂估毛利率:</span>
+                        <span>{{ scope.row.tempGrossMargin || '0.0000' }}%</span>
+                      </div>
+                    </div>
                   </template>
                   </template>
                 </el-table-column>
                 </el-table-column>
               </el-table>
               </el-table>
+              <pagination
+                v-show="tableData2.length > 0"
+                v-model:page="queryParams2.pageNum"
+                v-model:limit="queryParams2.pageSize"
+                v-model:way="queryParams2.way"
+                :cursor-mode="true"
+                :has-more="hasMore2"
+                @pagination="getTableData2"
+              />
             </div>
             </div>
-          </div>
-
-          <!-- 微页面链接选择区域 -->
-          <div v-else-if="isMicropageCategoryComputed" class="micropage-selection-container">
-            <!-- 搜索框 -->
-            <div class="product-search">
-              <el-input v-model="micropageSearchKeyword" placeholder="请输入微页面名称关键词" clearable @keyup.enter="handleMicropageSearch" />
-              <el-button type="primary" @click="handleMicropageSearch">搜索</el-button>
+            <!-- 采购方案 -->
+            <div v-if="boxpageKey == 'plan'">
+              <div class="flex justify-between">
+                <el-input v-model="queryParams3.tweetsTitle" placeholder="请输入方案主题" clearable style="width: 300px; margin-bottom: 10px">
+                  <template #append>
+                    <el-button :icon="Search" @click="handleQuery3" />
+                  </template>
+                </el-input>
+                <div>
+                  <span class="mr-[5px]">是否新窗口打开</span>
+                  <el-switch v-model="switchVal" />
+                </div>
+              </div>
+              <el-table v-loading="loading3" border :data="tableData3" height="480">
+                <el-table-column width="80" align="center">
+                  <template #default="{ row }">
+                    <el-checkbox v-model="tableId3" :true-value="row.id" />
+                  </template>
+                </el-table-column>
+                <el-table-column label="方案编号" align="center" prop="programNo" width="120" />
+                <el-table-column label="封面图片" align="center" prop="coverImage" width="100">
+                  <template #default="scope">
+                    <image-preview :src="scope.row.coverImage" :width="50" :height="50" />
+                  </template>
+                </el-table-column>
+                <el-table-column label="方案主题" align="center" prop="tweetsTitle" show-overflow-tooltip />
+                <el-table-column label="发布时间" align="center" prop="createTime" width="180">
+                  <template #default="scope">
+                    <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
+                  </template>
+                </el-table-column>
+              </el-table>
+              <pagination
+                v-show="total3 > 0"
+                :total="total3"
+                v-model:page="queryParams3.pageNum"
+                v-model:limit="queryParams3.pageSize"
+                @pagination="getTableData3"
+              />
             </div>
             </div>
-
-            <!-- 微页面列表 -->
-            <div class="micropage-list">
-              <el-table
-                :data="micropageList"
-                :style="{ width: '100%' }"
-                :row-class-name="({ row }) => (selectedMicropage?.id === row.id ? 'micropage-row-active' : '')"
-                @row-click="handleMicropageSelect"
-                class="custom-micropage-table"
-              >
-                <el-table-column width="80">
+            <!-- 产品推荐 -->
+            <div v-if="boxpageKey == 'procure'">
+              <div class="flex justify-between">
+                <el-input v-model="queryParams4.title" placeholder="请输入推文标题" clearable style="width: 300px; margin-bottom: 10px">
+                  <template #append>
+                    <el-button :icon="Search" @click="handleQuery4" />
+                  </template>
+                </el-input>
+                <div>
+                  <span class="mr-[5px]">是否新窗口打开</span>
+                  <el-switch v-model="switchVal" />
+                </div>
+              </div>
+              <el-table v-loading="loading4" border :data="tableData4" height="480">
+                <el-table-column width="80" align="center">
                   <template #default="{ row }">
                   <template #default="{ row }">
-                    <el-radio :model-value="selectedMicropage?.id" :label="row.id" @change="() => handleMicropageSelect(row)" />
+                    <el-checkbox v-model="tableId4" :true-value="row.id" />
+                  </template>
+                </el-table-column>
+                <el-table-column label="封面图片" align="center" prop="coverImageUrl" width="120">
+                  <template #default="scope">
+                    <image-preview :src="scope.row.coverImage" :width="60" :height="60" />
                   </template>
                   </template>
                 </el-table-column>
                 </el-table-column>
-                <el-table-column label="ID" prop="id" width="180" />
-                <el-table-column prop="name" label="标题名称名称">
+                <el-table-column label="推文标题" align="center" prop="title" min-width="200" show-overflow-tooltip>
+                  <template #default="scope">
+                    {{ scope.row.title }}
+                  </template>
+                </el-table-column>
+              </el-table>
+              <pagination
+                v-show="total4 > 0"
+                :total="total4"
+                v-model:page="queryParams4.pageNum"
+                v-model:limit="queryParams4.pageSize"
+                @pagination="getTableData4"
+              />
+            </div>
+            <!-- 采购指南 -->
+            <div v-if="boxpageKey == 'guide'">
+              <div class="flex justify-between">
+                <el-input v-model="queryParams5.title" placeholder="请输入标题" clearable style="width: 300px; margin-bottom: 10px">
+                  <template #append>
+                    <el-button :icon="Search" @click="handleQuery5" />
+                  </template>
+                </el-input>
+                <div>
+                  <span class="mr-[5px]">是否新窗口打开</span>
+                  <el-switch v-model="switchVal" />
+                </div>
+              </div>
+              <el-table v-loading="loading5" border :data="tableData5" height="480">
+                <el-table-column width="80" align="center">
                   <template #default="{ row }">
                   <template #default="{ row }">
-                    <div class="micropage-name">{{ row.name }}</div>
+                    <el-checkbox v-model="tableId5" :true-value="row.id" />
+                  </template>
+                </el-table-column>
+                <el-table-column label="标题" align="center" prop="title" min-width="200" show-overflow-tooltip>
+                  <template #default="scope">
+                    {{ scope.row.title }}
+                  </template>
+                </el-table-column>
+                <el-table-column label="发布时间" align="center" prop="releaseTime" width="120">
+                  <template #default="scope">
+                    <span>{{ parseTime(scope.row.releaseTime, '{y}-{m}-{d}') }}</span>
                   </template>
                   </template>
                 </el-table-column>
                 </el-table-column>
               </el-table>
               </el-table>
+              <pagination
+                v-show="total5 > 0"
+                :total="total5"
+                v-model:page="queryParams5.pageNum"
+                v-model:limit="queryParams5.pageSize"
+                @pagination="getTableData5"
+              />
             </div>
             </div>
-          </div>
-
-          <!-- 自定义链接输入区域 -->
-          <div v-else-if="isCustomLinkCategory" class="custom-link-container">
-            <el-form label-position="top">
-              <el-form-item label="跳转路径">
-                <el-input
-                  v-model="customLinkPath"
-                  placeholder="请输入跳转路径"
-                  clearable
-                  @input="() => emit('update:modelValue', customLinkPath.trim())"
-                >
-                  <template #prefix>
-                    <el-icon><Aim /></el-icon>
+            <!-- 项目案例 -->
+            <div v-if="boxpageKey == 'project'">
+              <div class="flex justify-between">
+                <el-input v-model="queryParams6.caseTitle" placeholder="请输入标题" clearable style="width: 300px; margin-bottom: 10px">
+                  <template #append>
+                    <el-button :icon="Search" @click="handleQuery6" />
                   </template>
                   </template>
                 </el-input>
                 </el-input>
-                <div class="custom-link-tips">
-                  <el-icon size="14"><Warning /></el-icon>
-                  <span>请确保链接格式正确,支持相对路径和绝对路径</span>
+                <div>
+                  <span class="mr-[5px]">是否新窗口打开</span>
+                  <el-switch v-model="switchVal" />
                 </div>
                 </div>
-              </el-form-item>
-            </el-form>
-          </div>
-
-          <!-- 预设链接展示区域 -->
-          <div v-else class="links-grid">
-            <el-button
-              v-for="link in currentLinks"
-              :key="link.id"
-              size="small"
-              :class="['link-button', { active: selectedLink && selectedLink.id === link.id }]"
-              :type="selectedLink && selectedLink.id === link.id ? 'primary' : 'default'"
-              :title="link.url"
-              @click="handleLinkClick(link)"
-            >
-              {{ link.name }}
-            </el-button>
-          </div>
-
-          <!-- 链接预览 -->
-          <div v-if="selectedLink || (isCustomLinkCategory && customLinkPath)" class="link-preview">
-            <span class="preview-label">当前选择:</span>
-            <span v-if="selectedLink" class="preview-name">{{ selectedLink.name }}</span>
-            <span v-else class="preview-name">自定义链接</span>
-            <span class="preview-path">{{ selectedLink ? selectedLink.url : customLinkPath }}</span>
-          </div>
+              </div>
+              <el-table v-loading="loading6" border :data="tableData6" height="480">
+                <el-table-column width="80" align="center">
+                  <template #default="{ row }">
+                    <el-checkbox v-model="tableId6" :true-value="row.id" />
+                  </template>
+                </el-table-column>
+                <el-table-column label="封面图片" align="center" width="120">
+                  <template #default="{ row }">
+                    <el-image
+                      :src="row.caseImage"
+                      fit="cover"
+                      style="width: 80px; height: 60px; border-radius: 4px"
+                      :preview-src-list="[row.caseImage]"
+                      preview-teleported
+                      lazy
+                    >
+                      <template #error>
+                        <div class="image-placeholder">
+                          <el-icon><Picture /></el-icon>
+                        </div>
+                      </template>
+                    </el-image>
+                  </template>
+                </el-table-column>
+                <el-table-column label="标题" align="center" prop="caseTitle" min-width="200" show-overflow-tooltip>
+                  <template #default="scope">
+                    {{ scope.row.caseTitle }}
+                  </template>
+                </el-table-column>
+                <el-table-column label="发布时间" align="center" prop="createTime" width="120">
+                  <template #default="scope">
+                    <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
+                  </template>
+                </el-table-column>
+              </el-table>
+              <pagination
+                v-show="total6 > 0"
+                :total="total6"
+                v-model:page="queryParams6.pageNum"
+                v-model:limit="queryParams6.pageSize"
+                @pagination="getTableData6"
+              />
+            </div>
+            <!-- 自定义 -->
+            <div v-if="boxpageKey == 'zdy'">
+              <div class="flex justify-between">
+                <el-input v-model="input" placeholder="请输入自定义链接" clearable style="width: 300px; margin-bottom: 10px"></el-input>
+                <div>
+                  <span class="mr-[5px]">是否新窗口打开</span>
+                  <el-switch v-model="switchVal" />
+                </div>
+              </div>
+            </div>
+          </template>
         </div>
         </div>
       </div>
       </div>
-    </div>
-
-    <!-- 底部按钮 -->
-    <template #footer>
-      <el-button @click="handleCancel">取消</el-button>
-      <el-button type="primary" @click="handleConfirm">确定</el-button>
-    </template>
-  </el-dialog>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="showDialog = false">取消</el-button>
+          <el-button type="primary" @click="onConfirm">确认</el-button>
+        </span>
+      </template>
+    </el-dialog>
+  </div>
 </template>
 </template>
 
 
 <script lang="ts" setup>
 <script lang="ts" setup>
-import { ref, computed, watch, nextTick, onMounted, onUnmounted } from 'vue';
-import type { TreeNode } from 'element-plus';
-import { ElMessage } from 'element-plus';
-import { Aim, Warning, Picture } from '@element-plus/icons-vue';
 import { getCategoryTree } from '@/api/mall/pageCategory/api';
 import { getCategoryTree } from '@/api/mall/pageCategory/api';
 import { listPageLink } from '@/api/mall/pageLink/api';
 import { listPageLink } from '@/api/mall/pageLink/api';
-import { pcDiyList } from '@/api/diy/index';
+import { CategoryVO } from '@/api/product/category/types';
+import { listCategory } from '@/api/product/category';
+import { Search } from '@element-plus/icons-vue';
 import { listBase } from '@/api/pmsProduct/base';
 import { listBase } from '@/api/pmsProduct/base';
+import { listProgram } from '@/api/product/program/index';
+import { programList } from '@/api/pmsProduct/program';
+import { listTopics } from '@/api/product/topics';
 import { listServiceCase } from '@/api/product/serviceCase';
 import { listServiceCase } from '@/api/product/serviceCase';
-
-interface LinkItem {
-  id: string;
-  name: string;
-  url: string;
-}
-
-// 商品数据接口
-interface ProductItem {
-  id: number;
-  name: string;
-  image: string;
-}
-
-// 文章数据接口
-interface ArticleItem {
-  id: number;
-  title: string;
-}
-
-// 微页面数据接口
-interface MicropageItem {
-  id: number;
-  name: string;
-}
-
-// Props
-interface Props {
-  visible: boolean;
-  modelValue?: string;
-}
-
-const props = withDefaults(defineProps<Props>(), {
-  visible: false,
-  modelValue: ''
+const showDialog = ref(false);
+const menuData = ref<any[]>([]);
+const defaultOpeneds = ref<any>(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10']);
+const defaultActive = ref('0-0');
+const boxData = ref<any>([]);
+const boxpageKey = ref<any>(null);
+const selected = ref<any>(null);
+const switchVal = ref<any>(true);
+//分类的列表
+const tableId1 = ref<any>(null);
+const loading1 = ref(true);
+const tableData1 = ref<any>([]);
+const selectedRowObj = ref<any>(null);
+// 存储懒加载的子节点加载状态和 resolve 函数
+const lazyTreeNodeMap = ref<Map<string | number, { tree: any; treeNode: any; resolve: (data: CategoryVO[]) => void }>>(new Map());
+//商品列表
+const tableId2 = ref<any>(null);
+const total2 = ref(0);
+const loading2 = ref(true);
+const tableData2 = ref<any>([]);
+const hasMore2 = ref(true); // 是否还有更多数据
+const queryParams2 = reactive({
+  pageNum: 1,
+  pageSize: 10,
+  way: undefined,
+  itemName: ''
 });
 });
-
-// Emits
-interface Emits {
-  'update:visible': [value: boolean];
-  'update:modelValue': [value: string];
-  'confirm': [value: string, link: LinkItem];
-  'cancel': [];
-  'close': [];
-  'reset': [];
-}
-
-const emit = defineEmits<Emits>();
-
-// 响应式数据
-const dialogVisible = computed({
-  get: () => props.visible,
-  set: (value) => emit('update:visible', value)
+//采购方案
+const tableId3 = ref<any>(null);
+const total3 = ref(0);
+const loading3 = ref(true);
+const tableData3 = ref<any>([]);
+const queryParams3 = reactive({
+  pageNum: 1,
+  pageSize: 10,
+  tweetsTitle: ''
 });
 });
+//产品推荐
+const tableId4 = ref<any>(null);
+const total4 = ref(0);
+const loading4 = ref(true);
+const tableData4 = ref<any>([]);
+const queryParams4 = reactive({
+  pageNum: 1,
+  pageSize: 10,
+  title: ''
+});
+//采购指南
+const tableId5 = ref<any>(null);
+const total5 = ref(0);
+const loading5 = ref(true);
+const tableData5 = ref<any>([]);
+const queryParams5 = reactive({
+  pageNum: 1,
+  pageSize: 10,
+  title: ''
+});
+//项目案例
+const tableId6 = ref<any>(null);
+const total6 = ref(0);
+const loading6 = ref(true);
+const tableData6 = ref<any>([]);
+const queryParams6 = reactive({
+  pageNum: 1,
+  pageSize: 10,
+  caseTitle: ''
+});
+//自定义
+const input = ref('');
 
 
-const treeRef = ref<InstanceType<(typeof import('element-plus'))['ElTree']>>();
-const selectedCategory = ref<any>();
-const selectedLink = ref<LinkItem>();
-const customLinkPath = ref('');
-const selectedProduct = ref<ProductItem>();
-const productList = ref<ProductItem[]>([]);
-const productSearchKeyword = ref('');
-const isProductCategory = ref(false);
-
-// 文章相关响应式数据
-const selectedArticle = ref<ArticleItem>();
-const articleList = ref<ArticleItem[]>([]);
-const articleSearchKeyword = ref('');
-const isArticleCategory = ref(false);
-
-// 微页面相关响应式数据
-// 获取DIY上下文
-const selectedMicropage = ref<MicropageItem>();
-const micropageList = ref<any[]>([]);
-const micropageSearchKeyword = ref('');
-const isMicropageCategory = ref(false);
+const emit = defineEmits(['update:modelValue']);
 
 
-// 动态树数据
-const treeData = ref<any[]>([]);
-// 分类对应的链接数据
-const categoryLinksMap = ref<Map<string | number, LinkItem[]>>(new Map());
+// 打开对话框的方法,用于外部调用
+const open = () => {
+  showDialog.value = true;
+  // 如果数据还没加载完成,则重新加载
+  if (menuData.value.length === 0) {
+    loadCategoryData();
+  } else {
+    boxData.value = menuData.value[0].children[0].children;
+  }
+};
 
 
 // 加载分类数据
 // 加载分类数据
 const loadCategoryData = async () => {
 const loadCategoryData = async () => {
   try {
   try {
     const res = await getCategoryTree();
     const res = await getCategoryTree();
-    if (res.data) {
-      // 只保留非顶级的分类
-      const filteredItems = res.data.find((item) => item.id === 0).children || [];
-      // 剩余的节点转换为树结构
-      const convertToTreeFormat = (items: any[]) => {
-        return items.map((item) => ({
-          id: item.id,
-          title: item.name,
-          originalData: item,
-          children: item.children ? convertToTreeFormat(item.children) : []
-        }));
-      };
-      treeData.value = convertToTreeFormat(filteredItems);
-      // 获取所有分类的 ID 列表
-      const allCategoryIds = getAllCategoryIds(treeData.value);
-
-      // 并行请求所有分类的链接数据
-      const linkPromises = allCategoryIds.map((id) => loadLinksForCategory(id));
-      const allLinks = await Promise.all(linkPromises);
-
-      // 将结果合并到 categoryLinksMap
-      allLinks.forEach((links, index) => {
-        const categoryId = allCategoryIds[index];
-        if (links && links.length > 0) {
-          categoryLinksMap.value.set(categoryId, links);
-        }
-      });
+    if (res.data && res.data.length > 0) {
+      const firstLevelChildren = res.data[0].children;
+      menuData.value = firstLevelChildren;
+      await Promise.all(firstLevelChildren.map((item: any) => processNode(item)));
+      boxData.value = menuData.value[0].children[0].children;
       return true;
       return true;
     }
     }
     return false;
     return false;
@@ -313,911 +452,371 @@ const loadCategoryData = async () => {
   }
   }
 };
 };
 
 
-// 递归获取所有分类 ID
-const getAllCategoryIds = (nodes: any[]): number[] => {
-  const ids: number[] = [];
-  nodes.forEach((node) => {
-    ids.push(node.id);
-    if (node.children && node.children.length > 0) {
-      ids.push(...getAllCategoryIds(node.children));
+const processNode = async (node: any) => {
+  if (node.children && node.children.length > 0 && node.type == 1) {
+    await Promise.all(node.children.map((child: any) => processNode(child)));
+  } else {
+    if ((!node.children || node.children.length === 0) && node.type == 1) {
+      try {
+        if (node.id) {
+          const res = await listPageLink({
+            cateId: node.id,
+            pageNum: 1,
+            pageSize: 100,
+            createTime: undefined
+          });
+          node.children = res.rows;
+        }
+      } catch (error) {
+        node.children = [];
+        console.error(`Failed to load links for node ${node.name}:`, error);
+      }
     }
     }
-  });
-  return ids;
+  }
 };
 };
 
 
-// 加载指定分类的链接数据
-const loadLinksForCategory = async (categoryId: number): Promise<LinkItem[]> => {
-  try {
-    const res = await listPageLink({
-      cateId: categoryId,
-      pageNum: 1,
-      pageSize: 100,
-      createTime: undefined
-    });
-    if (res.rows) {
-      return res.rows.map((item: any) => ({
-        id: item.linkKey,
-        name: item.name,
-        url: item.url
-      }));
+const onMenu = (res: any) => {
+  const list = res.split('-');
+  defaultActive.value = res;
+  if (res.startsWith('0')) {
+    boxData.value = menuData.value[list[0]].children[list[1]].children;
+  } else {
+    if (list.length == 2) {
+      const datas = menuData.value[list[0]].children[list[1]];
+      boxpageKey.value = datas.pageKey;
+      if (boxpageKey.value == 'goodsClassify') {
+        if (tableData1.value.length == 0) {
+          getTableData1();
+        }
+      }
+      if (boxpageKey.value == 'goodsItem') {
+        handleQuery2();
+      }
+      if (boxpageKey.value == 'plan') {
+        handleQuery3();
+      }
+      if (boxpageKey.value == 'procure') {
+        handleQuery4();
+      }
+      if (boxpageKey.value == 'guide') {
+        handleQuery5();
+      }
+      if (boxpageKey.value == 'project') {
+        handleQuery6();
+      }
+      console.log(datas, 'datas');
+    } else {
+      if (menuData.value[list[0]].type == '4') {
+        boxpageKey.value = 'zdy';
+      }
     }
     }
-    return [];
-  } catch (error) {
-    console.error(`获取分类 ${categoryId} 链接失败:`, error);
-    return [];
   }
   }
 };
 };
 
 
-// 默认树配置
-const defaultProps = {
-  children: 'children',
-  label: 'title'
+const getTableData1 = async () => {
+  loading1.value = true;
+  // 清空懒加载缓存
+  lazyTreeNodeMap.value.clear();
+  // 只加载顶级分类(parentId = 0)
+  const res = await listCategory({ parentId: 0 });
+  const data = (res as any).rows || res.data || [];
+  // 根据 hasChildren 字段标记是否有子节点
+  tableData1.value = data.map((item: CategoryVO) => ({
+    ...item,
+    hasChildren: item.hasChildren ?? item.classLevel < 3 // 如果后端没返回 hasChildren,根据 classLevel 判断
+  }));
+  loading1.value = false;
 };
 };
 
 
-// 当前显示的链接列表
-const currentLinks = computed(() => {
-  if (!selectedCategory.value || !selectedCategory.value.id) {
-    return [];
+/** 懒加载子节点 */
+const loadChildren = async (row: CategoryVO, treeNode: any, resolve: (data: CategoryVO[]) => void) => {
+  // 存储加载状态,便于刷新时重新加载
+  lazyTreeNodeMap.value.set(row.id, { tree: row, treeNode, resolve });
+  try {
+    const res = await listCategory({ parentId: row.id });
+    const data = (res as any).rows || res.data || [];
+    // 标记子节点是否还有子级
+    const children = data.map((item: CategoryVO) => ({
+      ...item,
+      hasChildren: item.hasChildren ?? item.classLevel < 3
+    }));
+    resolve(children);
+  } catch (error) {
+    resolve([]);
   }
   }
+};
 
 
-  // 从缓存中获取链接数据
-  return categoryLinksMap.value.get(selectedCategory.value.id) || [];
-});
-
-// 是否为自定义链接分类
-const isCustomLinkCategory = computed(() => {
-  return selectedCategory.value?.originalData?.type === '4' || selectedCategory.value?.name === '自定义链接';
-});
-
-// 是否为商品分类
-const isProductCategoryComputed = computed(() => {
-  return selectedCategory.value?.name === '商品' || selectedCategory.value?.title === '商品';
-});
-
-// 是否为文章分类
-const isArticleCategoryComputed = computed(() => {
-  return selectedCategory.value?.name === '文章' || selectedCategory.value?.title === '文章';
-});
-
-// 是否为微页面分类
-const isMicropageCategoryComputed = computed(() => {
-  return selectedCategory.value?.name === '微页面' || selectedCategory.value?.title === '微页面';
-});
-
-// 处理节点点击
-async function handleNodeClick(node: TreeNode) {
-  const treeNode = node as any;
-  if (treeNode.id) {
-    selectedCategory.value = treeNode;
-    selectedLink.value = undefined;
-    selectedProduct.value = undefined;
-    selectedArticle.value = undefined;
-    selectedMicropage.value = undefined;
+// 处理 Checkbox 点击
+const handleCheckboxChange = (row: any) => {
+  if (tableId1.value === row.id) {
+    selectedRowObj.value = row;
+  } else {
+    selectedRowObj.value = null;
+  }
+};
 
 
-    // 设置当前分类类型
-    isProductCategory.value = isProductCategoryComputed.value;
-    isArticleCategory.value = isArticleCategoryComputed.value;
-    isMicropageCategory.value = isMicropageCategoryComputed.value;
+//商品查询
+const handleQuery2 = () => {
+  queryParams2.pageNum = 1;
+  getTableData2();
+};
 
 
-    if (isProductCategory.value) {
-      // 如果是商品分类,清空搜索关键词并加载商品列表
-      productSearchKeyword.value = '';
-      await loadProductList();
-      emit('update:modelValue', '');
-    } else if (isArticleCategory.value) {
-      // 如果是文章分类,清空搜索关键词并加载文章列表
-      articleSearchKeyword.value = '';
-      await loadArticleList();
-      emit('update:modelValue', '');
-    } else if (isMicropageCategory.value) {
-      // 如果是微页面分类,清空搜索关键词并加载微页面列表
-      micropageSearchKeyword.value = '';
-      await loadMicropageList();
-      emit('update:modelValue', '');
-    } else if (isCustomLinkCategory.value) {
-      // 如果是自定义链接分类,清空选择
-      customLinkPath.value = '';
-      emit('update:modelValue', '');
-    } else {
-      // 获取当前分类的链接
-      const links = currentLinks.value;
-      if (links.length > 0) {
-        // 自动选择第一个链接
-        selectedLink.value = links[0];
-        emit('update:modelValue', links[0].url);
-      } else {
-        emit('update:modelValue', '');
-      }
-    }
+/** 获取列表商品 */
+const getTableData2 = async () => {
+  loading2.value = true;
+  try {
+    const res = await listBase(queryParams2);
+    tableData2.value = res.rows || [];
+    total2.value = res.total || 0;
+  } finally {
+    loading2.value = false;
   }
   }
-}
+};
+
+//采购方案查询
+const handleQuery3 = () => {
+  queryParams3.pageNum = 1;
+  getTableData3();
+};
 
 
-// 加载商品列表
-async function loadProductList(keyword: string = '') {
+/** 获取列表采购方案 */
+const getTableData3 = async () => {
+  loading3.value = true;
   try {
   try {
-    // 这里模拟获取商品数据,实际项目中应该调用API
-    const queryParams: any = {
-      pageNum: 1,
-      pageSize: 100,
-      itemName: keyword
-    };
-    const res = await listBase(queryParams);
-    if (res.rows) {
-      productList.value = res.rows.map((item: any) => ({
-        id: Number(item.id),
-        name: item.itemName,
-        image: item.productImage
-      }));
-    }
-  } catch (error) {
-    console.error('加载商品列表失败:', error);
-    ElMessage.error('加载商品列表失败');
-    productList.value = [];
+    const res = await listProgram(queryParams3);
+    tableData3.value = res.rows || [];
+    total3.value = res.total || 0;
+  } finally {
+    loading3.value = false;
   }
   }
-}
-
-// 搜索商品
-async function handleProductSearch() {
-  await loadProductList(productSearchKeyword.value);
-}
+};
 
 
-// 选择商品
-function handleProductSelect(product: ProductItem) {
-  selectedProduct.value = product;
-  // 构建商品详情链接:pages/goods/detail/detail?id=商品Id
-  const productUrl = `/pages/goods/detail/detail?id=${product.id}`;
-  emit('update:modelValue', productUrl);
-}
+//产品推荐查询
+const handleQuery4 = () => {
+  queryParams4.pageNum = 1;
+  getTableData4();
+};
 
 
-// 加载文章列表
-async function loadArticleList(keyword: string = '') {
+/** 获取列表产品推荐 */
+const getTableData4 = async () => {
+  loading4.value = true;
   try {
   try {
-    const queryParams = {
-      pageNum: 1,
-      pageSize: 100,
-      caseTitle: keyword
-    };
-
-    const res = await listServiceCase(queryParams);
-    if (res.data) {
-      articleList.value = res.data.map((item: any) => ({
-        id: item.id,
-        title: item.caseTitle
-      }));
-    }
-  } catch (error) {
-    console.error('加载文章列表失败:', error);
-    ElMessage.error('加载文章列表失败');
-    articleList.value = [];
+    const res = await programList(queryParams4);
+    tableData4.value = res.rows || [];
+    total4.value = res.total || 0;
+  } finally {
+    loading4.value = false;
   }
   }
-}
-
-// 搜索文章
-async function handleArticleSearch() {
-  await loadArticleList(articleSearchKeyword.value);
-}
+};
 
 
-// 选择文章
-function handleArticleSelect(article: ArticleItem) {
-  selectedArticle.value = article;
-  // 构建文章详情链接:pages/article/detail/detail?id=文章Id
-  const articleUrl = `/pages/article/detail/detail?id=${article.id}`;
-  emit('update:modelValue', articleUrl);
-}
+//采购指南查询
+const handleQuery5 = () => {
+  queryParams5.pageNum = 1;
+  getTableData5();
+};
 
 
-// 加载微页面列表
-async function loadMicropageList(keyword: string = '') {
+/** 获取列表采购指南 */
+const getTableData5 = async () => {
+  loading5.value = true;
   try {
   try {
-    // 这里模拟获取微页面数据,实际项目中应该调用API
-    // 假设的查询参数结构
-    const queryParams = {
-      pageNum: 1,
-      pageSize: 100,
-      title: keyword
-    };
-    let res = undefined;
-    res = await pcDiyList(queryParams);
-    if (res.rows) {
-      micropageList.value = res.list.map((item: any) => ({
-        id: item.id,
-        name: item.name
-      }));
-    }
-  } catch (error) {
-    console.error('加载微页面列表失败:', error);
-    ElMessage.error('加载微页面列表失败');
-    micropageList.value = [];
+    const res = await listTopics(queryParams5);
+    tableData5.value = res.rows || [];
+    total5.value = res.total || 0;
+  } finally {
+    loading5.value = false;
   }
   }
-}
+};
 
 
-// 搜索微页面
-async function handleMicropageSearch() {
-  await loadMicropageList(micropageSearchKeyword.value);
-}
+//项目案例查询
+const handleQuery6 = () => {
+  queryParams6.pageNum = 1;
+  getTableData6();
+};
 
 
-// 选择微页面
-function handleMicropageSelect(micropage: MicropageItem) {
-  selectedMicropage.value = micropage;
-  // 构建微页面链接:pages/micropage/detail/detail?id=微页面Id
-  const micropageUrl = `/pages/diy/index?id=${micropage.id}`;
-  emit('update:modelValue', micropageUrl);
-}
+/** 获取列表项目案例 */
+const getTableData6 = async () => {
+  loading6.value = true;
+  try {
+    const res = await listServiceCase(queryParams5);
+    tableData6.value = res.rows || [];
+    total6.value = res.total || 0;
+  } finally {
+    loading6.value = false;
+  }
+};
 
 
-// 处理链接点击
-function handleLinkClick(link: LinkItem) {
-  selectedLink.value = link;
-  // 触发临时选择事件,让父组件可以实时获取选择的链接
-  emit('update:modelValue', link.url);
-}
+const onSelected = (item: any) => {
+  selected.value = item.url;
+};
 
 
-// 处理确定
-function handleConfirm() {
-  if (isProductCategory.value) {
-    if (!selectedProduct.value) {
+const onConfirm = () => {
+  if (boxShow1.value) {
+    if (selected.value) {
+      emit('update:modelValue', `${selected.value}?openType=${switchVal.value ? 1 : 0}`);
+      showDialog.value = false;
+    } else {
       ElMessage({
       ElMessage({
-        message: '请选择商品',
+        message: '请选择一个链接',
         type: 'warning',
         type: 'warning',
         duration: 2000
         duration: 2000
       });
       });
-      return;
     }
     }
-    dialogVisible.value = false;
-    ElMessage({
-      message: '商品设置成功',
-      type: 'success',
-      duration: 2000
-    });
-  } else if (isArticleCategory.value) {
-    if (!selectedArticle.value) {
-      ElMessage({
-        message: '请选择文章',
-        type: 'warning',
-        duration: 2000
-      });
-      return;
+  } else {
+    if (boxpageKey.value == 'goodsClassify') {
+      if (tableId1.value) {
+        let url1 = '/search?type=' + selectedRowObj.value.classLevel;
+        if (selectedRowObj.value.classLevel == 1) {
+          url1 = url1 + '&topCategoryId=' + tableId1.value;
+        } else if (selectedRowObj.value.classLevel == 2) {
+          url1 = url1 + '&middleCategoryId=' + tableId1.value;
+        } else if (selectedRowObj.value.classLevel == 3) {
+          url1 = url1 + '&bottomCategoryId=' + tableId1.value;
+        }
+        url1 = url1 + '&openType=' + (switchVal.value ? 1 : 0);
+        emit('update:modelValue', url1);
+        showDialog.value = false;
+      } else {
+        ElMessage({
+          message: '请选择一个分类',
+          type: 'warning',
+          duration: 2000
+        });
+      }
     }
     }
-    dialogVisible.value = false;
-    ElMessage({
-      message: '文章设置成功',
-      type: 'success',
-      duration: 2000
-    });
-  } else if (isMicropageCategory.value) {
-    if (!selectedMicropage.value) {
-      ElMessage({
-        message: '请选择微页面',
-        type: 'warning',
-        duration: 2000
-      });
-      return;
+    if (boxpageKey.value == 'goodsItem') {
+      if (tableId2.value) {
+        let url2 = '/item?productNo=' + tableId2.value;
+        url2 = url2 + '&openType=' + (switchVal.value ? 1 : 0);
+        emit('update:modelValue', url2);
+        showDialog.value = false;
+      } else {
+        ElMessage({
+          message: '请选择一个商品',
+          type: 'warning',
+          duration: 2000
+        });
+      }
     }
     }
-    dialogVisible.value = false;
-    ElMessage({
-      message: '微页面设置成功',
-      type: 'success',
-      duration: 2000
-    });
-  } else if (isCustomLinkCategory.value) {
-    // 自定义链接处理
-    if (!customLinkPath.value.trim()) {
-      ElMessage({
-        message: '请输入自定义链接地址',
-        type: 'warning',
-        duration: 2000
-      });
-      return;
+    if (boxpageKey.value == 'plan') {
+      if (tableId3.value) {
+        let url3 = '/plan_info?id=' + tableId3.value;
+        url3 = url3 + '&openType=' + (switchVal.value ? 1 : 0);
+        emit('update:modelValue', url3);
+        showDialog.value = false;
+      } else {
+        ElMessage({
+          message: '请选择一个采购方案',
+          type: 'warning',
+          duration: 2000
+        });
+      }
     }
     }
-
-    // 验证链接格式
-    const path = customLinkPath.value.trim();
-    // 创建临时的自定义链接项
-    const customLink: LinkItem = {
-      id: `custom-${Date.now()}`,
-      name: '自定义链接',
-      url: path
-    };
-
-    emit('update:modelValue', path);
-    emit('confirm', path, customLink);
-    dialogVisible.value = false;
-    ElMessage({
-      message: '自定义链接设置成功',
-      type: 'success',
-      duration: 2000
-    });
-  } else if (selectedLink.value) {
-    // 普通链接处理
-    emit('update:modelValue', selectedLink.value.url);
-    emit('confirm', selectedLink.value.url, selectedLink.value);
-    dialogVisible.value = false;
-    // 确认选择后,显示成功提示
-    ElMessage({
-      message: '链接选择成功',
-      type: 'success',
-      duration: 2000
-    });
-  } else {
-    // 如果没有选择链接,提示用户
-    ElMessage({
-      message: '请选择一个链接',
-      type: 'warning',
-      duration: 2000
-    });
-  }
-}
-
-// 处理取消
-function handleCancel() {
-  emit('cancel');
-  dialogVisible.value = false;
-}
-
-// 打开对话框的方法,用于外部调用
-const open = () => {
-  dialogVisible.value = true;
-  // 如果数据还没加载完成,则重新加载
-  if (treeData.value.length === 0) {
-    loadCategoryData();
-  }
-};
-
-// 处理关闭
-function handleClose() {
-  emit('close');
-  // 对话框关闭时重置所有状态,不更新modelValue
-  selectedCategory.value = undefined;
-  selectedLink.value = undefined;
-  selectedProduct.value = undefined;
-  selectedArticle.value = undefined;
-  selectedMicropage.value = undefined;
-  if (treeRef.value) {
-    treeRef.value.setCurrentKey(null);
-  }
-}
-
-// 重置状态
-function resetState() {
-  selectedCategory.value = undefined;
-  selectedLink.value = undefined;
-  customLinkPath.value = '';
-  selectedProduct.value = undefined;
-  selectedArticle.value = undefined;
-  selectedMicropage.value = undefined;
-  productSearchKeyword.value = '';
-  articleSearchKeyword.value = '';
-  micropageSearchKeyword.value = '';
-
-  // 重置树的当前节点
-  if (treeRef.value) {
-    treeRef.value.setCurrentKey(null);
-  }
-}
-
-// 监听dialogVisible变化,当对话框打开时初始化状态
-watch(
-  () => dialogVisible.value,
-  async (newValue) => {
-    if (newValue) {
-      nextTick(async () => {
-        // 重置自定义链接输入
-        customLinkPath.value = '';
-        // 清空缓存
-        categoryLinksMap.value.clear();
-
-        // 加载分类数据
-        await loadCategoryData();
-
-        if (props.modelValue) {
-          // 如果有传入的modelValue,则尝试匹配
-        }
-
-        // 如果没有匹配的链接或没有传入modelValue,则设置默认选中
-        if (!selectedCategory.value && treeData.value.length > 0) {
-          // 找到第一个有子分类的节点
-          const findFirstNodeWithLinks = (nodes: any[]) => {
-            for (const node of nodes) {
-              if (node.children && node.children.length > 0) {
-                return node.children[0];
-              }
-            }
-            return null;
-          };
-
-          const firstNode = findFirstNodeWithLinks(treeData.value);
-          if (firstNode) {
-            selectedCategory.value = firstNode;
-            if (treeRef.value && firstNode.id) {
-              treeRef.value.setCurrentKey(firstNode.id);
-              // 触发节点点击,加载链接数据
-              await handleNodeClick(firstNode);
-            }
-          }
-        }
-      });
+    if (boxpageKey.value == 'procure') {
+      if (tableId4.value) {
+        let url4 = '/plan_info/procure?id=' + tableId4.value;
+        url4 = url4 + '&openType=' + (switchVal.value ? 1 : 0);
+        emit('update:modelValue', url4);
+        showDialog.value = false;
+      } else {
+        ElMessage({
+          message: '请选择一个产品推荐',
+          type: 'warning',
+          duration: 2000
+        });
+      }
     }
     }
-  }
-);
-
-// 键盘导航处理
-function handleKeyDown(event: KeyboardEvent) {
-  // 只有当对话框可见时才处理键盘事件
-  if (!dialogVisible.value || !selectedLink.value) return;
-
-  const links = currentLinks.value;
-  if (links.length === 0) return;
-
-  const currentIndex = links.findIndex((link) => link.id === selectedLink.value?.id);
-
-  switch (event.key) {
-    case 'ArrowRight':
-      // 向右箭头:选择下一个链接
-      event.preventDefault();
-      if (currentIndex < links.length - 1) {
-        handleLinkClick(links[currentIndex + 1]);
-      } else if (links.length > 0) {
-        handleLinkClick(links[0]);
+    if (boxpageKey.value == 'guide') {
+      if (tableId5.value) {
+        let url5 = '/plan_info/guide?id=' + tableId5.value;
+        url5 = url5 + '&openType=' + (switchVal.value ? 1 : 0);
+        emit('update:modelValue', url5);
+        showDialog.value = false;
+      } else {
+        ElMessage({
+          message: '请选择一个采购指南',
+          type: 'warning',
+          duration: 2000
+        });
       }
       }
-      break;
-    case 'ArrowLeft':
-      // 向左箭头:选择上一个链接
-      event.preventDefault();
-      if (currentIndex > 0) {
-        handleLinkClick(links[currentIndex - 1]);
-      } else if (links.length > 0) {
-        handleLinkClick(links[links.length - 1]);
+    }
+    if (boxpageKey.value == 'project') {
+      if (tableId6.value) {
+        let url6 = '/plan_info/project?id=' + tableId6.value;
+        url6 = url6 + '&openType=' + (switchVal.value ? 1 : 0);
+        emit('update:modelValue', url6);
+        showDialog.value = false;
+      } else {
+        ElMessage({
+          message: '请选择一个项目案例',
+          type: 'warning',
+          duration: 2000
+        });
       }
       }
-      break;
-    case 'Enter':
-      // 回车键:确认选择
-      event.preventDefault();
-      handleConfirm();
-      break;
-    case 'Escape':
-      // ESC键:取消
-      event.preventDefault();
-      handleCancel();
-      break;
+    }
+    if (boxpageKey.value == 'zdy') {
+      if (input.value) {
+        emit('update:modelValue', `${input.value}?openType=${switchVal.value ? 1 : 0}`);
+        showDialog.value = false;
+      } else {
+        ElMessage({
+          message: '请输入自定义链接',
+          type: 'warning',
+          duration: 2000
+        });
+      }
+    }
   }
   }
-}
-
-// 重置方法
-defineExpose({
-  reset: () => {
-    resetState();
-    emit('reset');
-    emit('update:modelValue', '');
-  },
-  open,
-  resetState
-});
+};
 
 
-// 组件挂载时添加键盘事件监听
-onMounted(() => {
-  document.addEventListener('keydown', handleKeyDown);
+const boxShow1 = computed(() => {
+  return defaultActive.value.startsWith('0');
 });
 });
 
 
-// 组件卸载时移除键盘事件监听
-onUnmounted(() => {
-  document.removeEventListener('keydown', handleKeyDown);
+defineExpose({
+  open
 });
 });
 </script>
 </script>
 
 
-<style scoped>
-/* 主容器样式 */
-.link-selector-container {
-  display: flex;
-  height: 800px;
-  gap: 20px;
-  animation: fadeIn 0.3s ease-in-out;
-}
-
-/* 商品链接选择区域样式 */
-.product-selection-container {
-  height: 100%;
-  display: flex;
-  flex-direction: column;
-}
-
-.product-search {
-  margin-bottom: 16px;
-}
-
-.product-search .el-input {
-  width: 30%;
-  margin-right: 8px;
-}
-
-.product-list {
-  flex: 1;
-  overflow-y: auto;
-}
-
-/* Element UI表格样式调整 */
-.product-list .el-table {
-  --el-table-header-bg-color: #1890ff;
-  --el-table-header-text-color: #ffffff;
-  --el-table-border-color: #e4e7ed;
-}
-
-.product-list .el-table :deep(.el-table__header th) {
-  font-weight: 500;
-  text-align: left;
-  padding: 12px;
-}
-
-.product-list .el-table :deep(.el-table__body td) {
-  padding: 12px;
-}
-
-.product-list .el-table :deep(.el-table__row:hover) {
-  background-color: #f5f7fa;
-}
-
-/* 选中行样式 */
-.product-row-active {
-  background-color: #ecf5ff !important;
-}
-
-/* 商品名称样式 */
-.product-name {
-  font-size: 14px;
-  line-height: 20px;
-  word-break: break-word;
-  max-width: 300px;
-}
-
-/* 左侧树容器 */
-.tree-container {
-  width: 200px;
-  border-right: 1px solid #e4e7ed;
-  overflow-y: auto;
-  background-color: #fafafa;
-  transition: all 0.3s ease;
-}
-
-/* 右侧链接容器 */
-.links-container {
-  flex: 1;
-  overflow-y: auto;
-  padding: 15px;
-  background-color: #ffffff;
-  border-radius: 4px;
+<style scoped lang="scss">
+.dialog-bos {
+  height: 580px;
   display: flex;
   display: flex;
-  flex-direction: column;
-  transition: all 0.3s ease;
-}
 
 
-/* 分类标题 */
-.category-title {
-  font-size: 16px;
-  font-weight: bold;
-  margin-bottom: 20px;
-  color: #303133;
-  padding-bottom: 8px;
-  border-bottom: 2px solid #409eff;
-  animation: slideInLeft 0.3s ease-out;
-}
-
-/* 链接网格 */
-.links-grid {
-  display: flex;
-  flex-wrap: wrap;
-  gap: 12px;
-  margin-bottom: 20px;
-}
-
-/* 自定义链接容器 */
-.custom-link-container {
-  animation: fadeInUp 0.3s ease-out;
-}
-
-/* 自定义链接提示 */
-.custom-link-tips {
-  margin-top: 8px;
-  font-size: 12px;
-  color: #909399;
-  display: flex;
-  align-items: flex-start;
-  gap: 4px;
-  word-break: break-all;
-  flex-wrap: wrap;
-  width: 100%;
-}
-
-.custom-link-tips .el-icon {
-  color: #e6a23c;
-}
-
-/* 链接按钮 */
-.link-button {
-  margin-bottom: 8px;
-  transition: all 0.3s ease;
-  min-width: 120px;
-  animation: fadeInUp 0.3s ease-out;
-}
-
-.link-button:hover {
-  transform: translateY(-1px);
-  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
-}
-
-.link-button.active {
-  background-color: #409eff;
-  color: white;
-  animation: pulse 0.5s ease-in-out;
-}
-
-/* 链接预览区域 */
-.link-preview {
-  margin-top: auto;
-  padding: 12px;
-  background-color: #f5f7fa;
-  border-radius: 4px;
-  border-left: 4px solid #409eff;
-  font-size: 14px;
-  animation: slideInUp 0.4s ease-out;
-  transition: all 0.3s ease;
-}
-
-.link-preview:hover {
-  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
-}
-
-.preview-label {
-  color: #606266;
-  font-weight: 500;
-}
-
-.preview-name {
-  color: #409eff;
-  font-weight: bold;
-  margin: 0 8px;
-}
-
-.preview-path {
-  color: #909399;
-  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
-  word-break: break-all;
-}
-
-/* 滚动条样式 */
-.tree-container::-webkit-scrollbar,
-.links-container::-webkit-scrollbar {
-  width: 6px;
-  height: 6px;
-}
-
-.tree-container::-webkit-scrollbar-thumb,
-.links-container::-webkit-scrollbar-thumb {
-  background-color: #dcdfe6;
-  border-radius: 3px;
-  transition: background-color 0.3s;
-}
-
-.tree-container::-webkit-scrollbar-thumb:hover,
-.links-container::-webkit-scrollbar-thumb:hover {
-  background-color: #c0c4cc;
-}
-
-.tree-container::-webkit-scrollbar-track,
-.links-container::-webkit-scrollbar-track {
-  background-color: #f5f7fa;
-}
-
-/* Element Plus 树样式覆盖 */
-:deep(.el-tree-node) {
-  padding: 2px 0;
-  transition: all 0.2s ease;
-}
-
-:deep(.el-tree-node__content) {
-  transition: all 0.3s ease;
-  padding: 8px 12px;
-  margin: 0;
-}
-
-:deep(.el-tree-node__content:hover) {
-  background-color: #ecf5ff;
-  transform: translateX(2px);
-}
-
-:deep(.el-tree-node.is-current > .el-tree-node__content) {
-  background-color: #ecf5ff;
-  color: #409eff;
-  font-weight: 500;
-  border-right: 3px solid #409eff;
-}
-
-:deep(.el-tree-node.is-current > .el-tree-node__content .el-tree-node__label) {
-  color: #409eff;
-}
-
-/* 自定义表格样式 */
-:deep(.custom-product-table .el-table__header th) {
-  background-color: #188fff54 !important;
-}
-
-/* 移除单选框后面的点 */
-:deep(.el-radio__label) {
-  display: none;
-}
-
-/* 确保单选框样式正确 */
-:deep(.el-radio) {
-  margin-right: 0;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-}
-
-/* 图片加载失败时的样式 */
-:deep(.image-slot) {
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  width: 80px;
-  height: 60px;
-  background-color: #f5f7fa;
-  color: #909399;
-}
-
-/* 动画定义 */
-@keyframes fadeIn {
-  from {
-    opacity: 0;
-  }
-  to {
-    opacity: 1;
-  }
-}
-
-@keyframes slideInLeft {
-  from {
-    opacity: 0;
-    transform: translateX(-20px);
-  }
-  to {
-    opacity: 1;
-    transform: translateX(0);
-  }
-}
-
-@keyframes slideInUp {
-  from {
-    opacity: 0;
-    transform: translateY(20px);
-  }
-  to {
-    opacity: 1;
-    transform: translateY(0);
-  }
-}
-
-@keyframes fadeInUp {
-  from {
-    opacity: 0;
-    transform: translateY(10px);
-  }
-  to {
-    opacity: 1;
-    transform: translateY(0);
-  }
-}
-
-@keyframes pulse {
-  0% {
-    transform: scale(1);
-  }
-  50% {
-    transform: scale(1.05);
-  }
-  100% {
-    transform: scale(1);
-  }
-}
-
-/* 响应式设计 */
-@media (max-width: 1200px) {
-  .link-selector-container {
-    height: 350px;
-  }
-
-  .tree-container {
-    width: 180px;
-  }
-}
-
-@media (max-width: 768px) {
-  .link-selector-container {
-    height: 300px;
-    gap: 10px;
-  }
-
-  .tree-container {
-    width: 160px;
-  }
-
-  .links-container {
-    padding: 10px;
-  }
-
-  .link-button {
-    min-width: 100px;
-    padding: 8px 12px;
-    font-size: 13px;
-  }
-
-  .category-title {
-    font-size: 14px;
-    margin-bottom: 15px;
+  .menu-container {
+    height: 100%;
+    width: 140px;
+    overflow: auto;
   }
   }
 
 
-  .link-preview {
-    font-size: 12px;
-    padding: 8px;
-  }
-}
+  .dialog-box {
+    flex: 1;
+    padding: 0 20px 20px 20px;
 
 
-@media (max-width: 480px) {
-  .link-selector-container {
-    flex-direction: column;
-    height: 450px;
-  }
+    .button-title {
+      margin: 15px 0;
 
 
-  .tree-container {
-    width: 100%;
-    height: 120px;
-    border-right: none;
-    border-bottom: 1px solid #e4e7ed;
-  }
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      .title {
+        font-size: 14px;
+        font-weight: 600;
+      }
+    }
 
 
-  .links-container {
-    flex: 1;
-  }
+    .button-container {
+      display: flex;
+      flex-wrap: wrap;
+      gap: 10px;
 
 
-  .links-grid {
-    gap: 8px;
+      :deep(.el-button + .el-button) {
+        margin-left: 0px;
+      }
+    }
   }
   }
 
 
-  .link-button {
-    min-width: calc(50% - 4px);
-    margin-bottom: 0;
+  :deep(.pagination-container) {
+    margin-top: 0px;
   }
   }
 }
 }
-
-/* 加载动画 */
-:deep(.el-loading-spinner) {
-  margin-top: -20px;
-}
-
-/* 确保对话框在小屏幕上也能良好显示 */
-:deep(.el-dialog__wrapper) {
-  display: flex;
-  align-items: center;
-  justify-content: center;
-}
-
-:deep(.el-dialog) {
-  margin: 0 !important;
-  max-height: 90vh;
-  display: flex;
-  flex-direction: column;
-}
-
-:deep(.el-dialog__body) {
-  flex: 1;
-  overflow-y: auto;
-  padding: 20px;
-}
-
-/* 当选择链接时的反馈 */
-:deep(.el-button--primary.is-active) {
-  background-color: #337ecc;
-  border-color: #337ecc;
-}
-
-/* 确保选中行样式正确 */
-.product-row-active {
-  background-color: #e6f7ff !important;
-}
 </style>
 </style>

+ 1 - 1
src/views/diy/pccomponents/pages/textTitle.vue

@@ -3,7 +3,7 @@
     <div :style="warpCss">
     <div :style="warpCss">
       <!-- 风格1 -->
       <!-- 风格1 -->
       <div :style="boxCss" v-if="componentData.styleType == 1">
       <div :style="boxCss" v-if="componentData.styleType == 1">
-        <div class="hover-color" :style="titleCss">{{ componentData.title }}{{ componentData.titleUrl }}</div>
+        <div class="hover-color" :style="titleCss">{{ componentData.title }}</div>
       </div>
       </div>
       <!-- 风格2 -->
       <!-- 风格2 -->
       <div :style="boxCss" class="style2 flex-row-center" v-else-if="componentData.styleType == 2">
       <div :style="boxCss" class="style2 flex-row-center" v-else-if="componentData.styleType == 2">

+ 1 - 1
src/views/platform/decoration/floorAd/index.vue

@@ -86,7 +86,7 @@
               </el-col>
               </el-col>
               <el-col :span="12">
               <el-col :span="12">
                 <el-form-item label="链接:">
                 <el-form-item label="链接:">
-                  <el-input v-model="form.link" placeholder="请输入链接地址" />
+                  <WebLinkInput v-model="form.link" placeholder="请输入或选择链接" />
                 </el-form-item>
                 </el-form-item>
               </el-col>
               </el-col>
             </el-row>
             </el-row>

+ 1 - 1
src/views/platform/decoration/recommend/index.vue

@@ -76,7 +76,7 @@
           </el-col>
           </el-col>
           <el-col :span="12">
           <el-col :span="12">
             <el-form-item label="链接" prop="advertUrl">
             <el-form-item label="链接" prop="advertUrl">
-              <el-input v-model="sceneForm.advertUrl" placeholder="请输入链接" />
+              <WebLinkInput v-model="sceneForm.advertUrl" placeholder="请输入或选择链接" />
             </el-form-item>
             </el-form-item>
           </el-col>
           </el-col>
         </el-row>
         </el-row>

+ 2 - 2
src/views/platform/gift/banner/index.vue

@@ -264,12 +264,12 @@ onMounted(() => {
 .action-link {
 .action-link {
   cursor: pointer;
   cursor: pointer;
   margin: 0 6px;
   margin: 0 6px;
-  
+
   &.primary {
   &.primary {
     color: #409eff;
     color: #409eff;
     &:hover { color: #66b1ff; }
     &:hover { color: #66b1ff; }
   }
   }
-  
+
   &.danger {
   &.danger {
     color: #f56c6c;
     color: #f56c6c;
     &:hover { color: #f78989; }
     &:hover { color: #f78989; }

+ 2 - 2
src/views/platform/industrial/floorAd/index.vue

@@ -430,11 +430,11 @@ onMounted(() => {
     padding: 8px 12px;
     padding: 8px 12px;
     border-radius: 4px;
     border-radius: 4px;
     border: 2px solid transparent;
     border: 2px solid transparent;
-    
+
     &:hover {
     &:hover {
       background: #f5f5f5;
       background: #f5f5f5;
     }
     }
-    
+
     &.active {
     &.active {
       border-color: #409eff;
       border-color: #409eff;
       background: #ecf5ff;
       background: #ecf5ff;