Browse Source

修复bug

weixin_52219567 1 tháng trước cách đây
mục cha
commit
98d77ba9ba
66 tập tin đã thay đổi với 1781 bổ sung953 xóa
  1. 10 0
      src/api/goods/index.ts
  2. 19 0
      src/api/home/diy.ts
  3. BIN
      src/assets/images/layout/workbench.png
  4. BIN
      src/assets/images/layout/workbench1.png
  5. BIN
      src/assets/images/layout/workbench2.png
  6. BIN
      src/assets/images/layout/workbench3.png
  7. BIN
      src/assets/images/layout/workbench4.png
  8. BIN
      src/assets/images/layout/workbench5.png
  9. BIN
      src/assets/images/layout/workbench6.png
  10. BIN
      src/assets/images/layout/workbench7.png
  11. BIN
      src/assets/images/pcdiy/activity1.png
  12. BIN
      src/assets/images/pcdiy/activity2.png
  13. BIN
      src/assets/images/pcdiy/activity3-1.png
  14. BIN
      src/assets/images/pcdiy/activity3.png
  15. BIN
      src/assets/images/pcdiy/activity4-1.png
  16. BIN
      src/assets/images/pcdiy/activity4.png
  17. BIN
      src/assets/images/pcdiy/activity5.png
  18. BIN
      src/assets/images/pcdiy/activity6.png
  19. BIN
      src/assets/images/pcdiy/activity7.png
  20. BIN
      src/assets/images/pcdiy/activity8.png
  21. 0 28
      src/components/EmptyState/index.vue
  22. 0 218
      src/components/HeaderBar/index.vue
  23. 51 0
      src/components/icon/index.vue
  24. 1 3
      src/components/index.ts
  25. 142 52
      src/layout/components/header.vue
  26. 2 1
      src/layout/components/search.vue
  27. 241 105
      src/layout/components/workbench.vue
  28. 6 1
      src/layout/index.vue
  29. 55 28
      src/permission.ts
  30. 28 10
      src/router/index.ts
  31. 11 1
      src/store/modules/station.ts
  32. 4 17
      src/store/modules/user.ts
  33. 1 2
      src/types/components.d.ts
  34. 4 5
      src/utils/siteConfig.ts
  35. 10 1
      src/views/breg/index.vue
  36. 44 30
      src/views/cart/index.vue
  37. 32 3
      src/views/greg/index.vue
  38. 0 35
      src/views/home/diy copy.vue
  39. 7 1
      src/views/home/diy.vue
  40. 27 0
      src/views/home/index-dataDiy.vue
  41. 19 0
      src/views/home/index-fuliDiy.vue
  42. 19 0
      src/views/home/index-mroDiy.vue
  43. 4 4
      src/views/home/index.vue
  44. 19 0
      src/views/home/indexDiy.vue
  45. 63 41
      src/views/home/pccomponents/index.ts
  46. 57 0
      src/views/home/pccomponents/index.vue
  47. 287 94
      src/views/home/pccomponents/pages/activity.vue
  48. 15 2
      src/views/home/pccomponents/pages/advert.vue
  49. 2 0
      src/views/home/pccomponents/pages/article.vue
  50. 80 0
      src/views/home/pccomponents/pages/blank.vue
  51. 90 0
      src/views/home/pccomponents/pages/border.vue
  52. 4 0
      src/views/home/pccomponents/pages/brand.vue
  53. 2 1
      src/views/home/pccomponents/pages/carousel.vue
  54. 64 49
      src/views/home/pccomponents/pages/discover.vue
  55. 81 0
      src/views/home/pccomponents/pages/editordiy.vue
  56. 31 23
      src/views/home/pccomponents/pages/floor.vue
  57. 99 65
      src/views/home/pccomponents/pages/goods.vue
  58. 38 37
      src/views/home/pccomponents/pages/goodsList.vue
  59. 23 35
      src/views/home/pccomponents/pages/head.vue
  60. 13 15
      src/views/home/pccomponents/pages/hot.vue
  61. 2 1
      src/views/home/pccomponents/pages/imageCube.vue
  62. 15 2
      src/views/home/pccomponents/pages/navigation.vue
  63. 18 16
      src/views/home/pccomponents/pages/textTitle.vue
  64. 23 20
      src/views/item/index.vue
  65. 12 3
      src/views/search/index.vue
  66. 6 4
      src/views/trad/index.vue

+ 10 - 0
src/api/goods/index.ts

@@ -37,6 +37,16 @@ export const deleteProductShoppingCart = (ids: any) => {
   });
 };
 
+//修改购物车数量
+
+export const updateProductShoppingCart = (params: any) => {
+  return request({
+    url: '/product/myProduct/updateProductShoppingCart',
+    method: 'post',
+    data: params
+  });
+};
+
 //导出购物车的商品
 export const exportProductShoppingCart = (data?: any) => {
   return request({

+ 19 - 0
src/api/home/diy.ts

@@ -45,3 +45,22 @@ export function getBigCustomerPlatformIndexDiyPcPage(query: any) {
     params: query
   });
 }
+
+//查询3个首页的diy
+export function getIndexDiyPcPage(query: any) {
+  return request({
+    url: '/mall/indexDiyPcPage/getIndexDiyPcPage',
+    method: 'get',
+    params: query
+  });
+}
+
+//查询首页是否开启diy
+
+export function getIsUseDiy(query: any) {
+  return request({
+    url: '/system/diySystem/getIsUseDiy',
+    method: 'get',
+    params: query
+  });
+}

BIN
src/assets/images/layout/workbench.png


BIN
src/assets/images/layout/workbench1.png


BIN
src/assets/images/layout/workbench2.png


BIN
src/assets/images/layout/workbench3.png


BIN
src/assets/images/layout/workbench4.png


BIN
src/assets/images/layout/workbench5.png


BIN
src/assets/images/layout/workbench6.png


BIN
src/assets/images/layout/workbench7.png


BIN
src/assets/images/pcdiy/activity1.png


BIN
src/assets/images/pcdiy/activity2.png


BIN
src/assets/images/pcdiy/activity3-1.png


BIN
src/assets/images/pcdiy/activity3.png


BIN
src/assets/images/pcdiy/activity4-1.png


BIN
src/assets/images/pcdiy/activity4.png


BIN
src/assets/images/pcdiy/activity5.png


BIN
src/assets/images/pcdiy/activity6.png


BIN
src/assets/images/pcdiy/activity7.png


BIN
src/assets/images/pcdiy/activity8.png


+ 0 - 28
src/components/EmptyState/index.vue

@@ -1,28 +0,0 @@
-<template>
-  <div class="empty-state">
-    <el-empty :description="description" :image-size="imageSize">
-      <template v-if="$slots.default" #default>
-        <slot></slot>
-      </template>
-    </el-empty>
-  </div>
-</template>
-
-<script setup lang="ts">
-withDefaults(
-  defineProps<{
-    description?: string;
-    imageSize?: number;
-  }>(),
-  {
-    description: '暂无数据',
-    imageSize: 120
-  }
-);
-</script>
-
-<style scoped lang="scss">
-.empty-state {
-  padding: 40px 0;
-}
-</style>

+ 0 - 218
src/components/HeaderBar/index.vue

@@ -1,218 +0,0 @@
-<template>
-  <header class="layout-header">
-    <!-- 顶部工具栏 -->
-    <div class="header-top">
-      <div class="header-top-content">
-        <div class="location">
-          <el-icon><Location /></el-icon> 武汉
-        </div>
-        <div class="top-links">
-          <span>您好,请登录</span>
-          <span class="link highlight">免费注册</span>
-          <span class="divider">|</span>
-          <span class="link">工作台</span>
-          <span class="divider">|</span>
-          <span class="link"
-            >采购合作 <el-icon><ArrowDown /></el-icon
-          ></span>
-          <span class="divider">|</span>
-          <span class="link"
-            >客户服务 <el-icon><ArrowDown /></el-icon
-          ></span>
-          <span class="divider">|</span>
-          <span class="link">帮助中心</span>
-          <span class="divider">|</span>
-          <span class="link">在线客服</span>
-        </div>
-      </div>
-    </div>
-    <!-- 主导航栏 -->
-    <div class="header-main">
-      <div class="header-main-content">
-        <div class="logo">
-          <img src="@/assets/logo.png" alt="logo" class="logo-img" />
-          <span class="logo-text">优易</span>
-        </div>
-        <div class="search-box">
-          <el-input v-model="searchKeyword" placeholder="搜索商品、品牌、分类..." class="search-input" @keyup.enter="handleSearch">
-            <template #append>
-              <el-button type="danger" class="search-btn" @click="handleSearch"
-                ><el-icon><Search /></el-icon
-              ></el-button>
-            </template>
-          </el-input>
-          <div class="hot-keywords">
-            <span v-for="(word, index) in hotKeywords" :key="index" class="keyword" @click="handleKeywordClick(word)">{{ word }}</span>
-          </div>
-        </div>
-        <div class="cart-box">
-          <el-button class="cart-btn" @click="handleCartClick"
-            ><el-icon><ShoppingCart /></el-icon> 我的采购车</el-button
-          >
-        </div>
-        <div class="qrcode-box">
-          <div class="qrcode-placeholder"></div>
-        </div>
-      </div>
-    </div>
-  </header>
-</template>
-
-<script setup lang="ts">
-import { ref } from 'vue';
-import { Location, ArrowDown, Search, ShoppingCart } from '@element-plus/icons-vue';
-
-const searchKeyword = ref('');
-const hotKeywords = ['家纺', '打印机', '打印耗材', '空调', '取暖', '开门红', '劳保福利'];
-
-const emit = defineEmits<{
-  search: [keyword: string];
-  cartClick: [];
-}>();
-
-const handleSearch = () => {
-  emit('search', searchKeyword.value);
-};
-
-const handleKeywordClick = (word: string) => {
-  searchKeyword.value = word;
-  emit('search', word);
-};
-
-const handleCartClick = () => {
-  emit('cartClick');
-};
-</script>
-
-<style scoped lang="scss">
-.layout-header {
-  background: #fff;
-
-  .header-top {
-    background: #f5f5f5;
-    font-size: 12px;
-    color: #666;
-
-    .header-top-content {
-      max-width: 1200px;
-      margin: 0 auto;
-      padding: 8px 0;
-      display: flex;
-      justify-content: space-between;
-      align-items: center;
-    }
-
-    .location {
-      display: flex;
-      align-items: center;
-      gap: 4px;
-    }
-
-    .top-links {
-      display: flex;
-      align-items: center;
-      gap: 8px;
-
-      .link {
-        cursor: pointer;
-        display: flex;
-        align-items: center;
-        gap: 2px;
-        &:hover {
-          color: #e60012;
-        }
-        &.highlight {
-          color: #e60012;
-        }
-      }
-      .divider {
-        color: #ddd;
-      }
-    }
-  }
-
-  .header-main {
-    border-bottom: 2px solid #e60012;
-
-    .header-main-content {
-      max-width: 1200px;
-      margin: 0 auto;
-      padding: 20px 0;
-      display: flex;
-      align-items: center;
-      gap: 40px;
-    }
-
-    .logo {
-      display: flex;
-      align-items: center;
-      gap: 8px;
-      cursor: pointer;
-      .logo-img {
-        height: 50px;
-      }
-      .logo-text {
-        font-size: 28px;
-        font-weight: bold;
-        color: #e60012;
-      }
-    }
-
-    .search-box {
-      flex: 1;
-      .search-input {
-        :deep(.el-input__wrapper) {
-          border-radius: 0;
-        }
-        :deep(.el-input-group__append) {
-          padding: 0;
-          background: #e60012;
-          border: none;
-        }
-      }
-      .search-btn {
-        background: #e60012;
-        border: none;
-        color: #fff;
-        height: 40px;
-        width: 60px;
-        border-radius: 0;
-      }
-      .hot-keywords {
-        margin-top: 8px;
-        display: flex;
-        gap: 16px;
-        .keyword {
-          font-size: 12px;
-          color: #666;
-          cursor: pointer;
-          &:hover {
-            color: #e60012;
-          }
-        }
-      }
-    }
-
-    .cart-box {
-      .cart-btn {
-        border: 1px solid #e60012;
-        color: #e60012;
-        background: #fff;
-        padding: 10px 20px;
-        &:hover {
-          background: #fff5f5;
-        }
-      }
-    }
-
-    .qrcode-box {
-      .qrcode-placeholder {
-        width: 80px;
-        height: 80px;
-        background: #f5f5f5;
-        border: 1px solid #eee;
-      }
-    }
-  }
-}
-</style>

+ 51 - 0
src/components/icon/index.vue

@@ -0,0 +1,51 @@
+<template>
+  <el-icon v-if="type == 'element'" :style="style" :class="['icon el-icon', props.class]">
+    <component :is="name" />
+  </el-icon>
+  <i v-else :class="[type, name, props.class]" :style="style"></i>
+</template>
+<script lang="ts" setup>
+import { watch, ref, reactive } from 'vue';
+
+const props = defineProps({
+  name: {
+    type: String,
+    required: true
+  },
+  color: {
+    type: String,
+    default: 'var(--color)'
+  },
+  class: {
+    type: [String, Object],
+    default: ''
+  },
+  size: {
+    type: String,
+    default: '16px'
+  }
+});
+
+const type = ref('');
+const name = ref('');
+
+const style = reactive({
+  color: props.color,
+  fontSize: props.size
+});
+
+const load = () => {
+  const arr = props.name.split(' ');
+  type.value = arr[0];
+  name.value = arr[1];
+};
+
+load();
+
+watch(
+  () => props.name,
+  () => {
+    load();
+  }
+);
+</script>

+ 1 - 3
src/components/index.ts

@@ -6,8 +6,6 @@ import ProductCard from './ProductCard/index.vue';
 import SearchBar from './SearchBar/index.vue';
 import StatCards from './StatCards/index.vue';
 import TablePagination from './TablePagination/index.vue';
-import HeaderBar from './HeaderBar/index.vue';
-import EmptyState from './EmptyState/index.vue';
 import TableActions from './TableActions/index.vue';
 
-export { PageTitle, StatusTabs, ProductItem, ProductCard, SearchBar, StatCards, TablePagination, HeaderBar, EmptyState, TableActions };
+export { PageTitle, StatusTabs, ProductItem, ProductCard, SearchBar, StatCards, TablePagination, TableActions };

+ 142 - 52
src/layout/components/header.vue

@@ -1,10 +1,12 @@
 <template>
   <!-- 头部组件 -->
   <div class="header flex-row-center">
-    <div class="header-bos flex-row-between">
-      <div class="flex-row-start mr-[20px]">
+    <div class="header-bos">
+      <div class="header-left flex-row-start">
         <div class="positioning flex-row-start" @click="onPath('/')">
-          <el-icon size="20"><HomeFilled /></el-icon>
+          <el-icon size="18">
+            <HomeFilled />
+          </el-icon>
           <div class="ml-[10px]">首页</div>
         </div>
         <div class="positioning flex-row-start ml-[20px]">
@@ -12,33 +14,30 @@
           <div>武汉</div>
         </div>
       </div>
-
-      <div class="header-box flex-row-start">
-        <el-dropdown v-if="userInfo.customerName">
-          <div class="dropdow header-text hig">
-            {{ userInfo.customerName }}
-            <el-icon><ArrowDown /></el-icon>
+      <div class="header-right">
+        <div
+          class="userInfo-bos"
+          :class="{ 'open': userInfoOpen }"
+          v-if="userInfo.user"
+          @mouseenter="handleMouseEnter"
+          @mouseleave="handleMouseLeave"
+        >
+          <div class="userInfo-customer">
+            <div class="mr-[5px]">{{ userInfo.customerName || '' }}</div>
+            <el-icon>
+              <ArrowDown />
+            </el-icon>
           </div>
-          <template #dropdown>
-            <el-dropdown-menu>
-              <el-dropdown-item>
-                <span></span>
-                <span class="hig">{{ userInfo.customerName }}</span>
-              </el-dropdown-item>
-              <el-dropdown-item>
-                <span>姓名:{{ userInfo.nickName }}</span>
-              </el-dropdown-item>
-              <el-dropdown-item divided @click="onlogout">退出登录</el-dropdown-item>
-            </el-dropdown-menu>
-          </template>
-        </el-dropdown>
-        <div v-if="!userInfo.nickName" class="header-text" @click="onPath('/login')" style="cursor: pointer">请登录</div>
-        <div v-if="!userInfo.nickName" class="header-text hig" @click="onPath('/breg')">免费注册</div>
+          <div class="userInfo-box">姓名:{{ userInfo.user.nickName }}</div>
+          <div class="userInfo-box" @click="onlogout">退出登录</div>
+        </div>
+        <div v-if="!userInfo.user" class="header-text end" @click="onPath('/login')" style="cursor: pointer">请登录</div>
+        <div v-if="!userInfo.user" class="header-text hig" @click="onPath('/breg')">免费注册</div>
         <div class="header-text" @click="onPath('/order/orderManage')">我的订单</div>
         <div class="header-text" @click="onPath('/enterprise/companyInfo')">会员中心</div>
         <div class="header-text" @click="onPath('/theme?id=1')">人才招聘</div>
         <div class="header-text">帮助中心</div>
-        <div class="header-text end">在线客服</div>
+        <div class="header-text">在线客服</div>
       </div>
     </div>
   </div>
@@ -51,22 +50,74 @@ import { computed } from 'vue';
 import { onPath } from '@/utils/siteConfig';
 import Cookies from 'js-cookie';
 import { getInfo } from '@/api/login';
+const userInfoOpen = ref<any>(false);
 const userInfo = ref<any>({});
+const router = useRouter();
+const userStore = useUserStore();
 
 onMounted(() => {
+  // getCurrentLocation();
   const token = Cookies.get('Authorization');
   if (token) {
     getInfo().then((res) => {
       if (res.code == 200) {
-        userInfo.value = res.data.user;
-        userInfo.value.customerName = res.data.customerName || '';
+        userInfo.value = res.data;
       }
     });
   }
 });
 
-const router = useRouter();
-const userStore = useUserStore();
+const handleMouseEnter = () => {
+  userInfoOpen.value = true;
+};
+
+const handleMouseLeave = () => {
+  userInfoOpen.value = false;
+};
+
+/**
+ * 获取浏览器定位并转换
+ */
+const getCurrentLocation = () => {
+  if (!navigator.geolocation) {
+    return Promise.reject('您的浏览器不支持地理定位');
+  }
+
+  return new Promise<any>((resolve, reject) => {
+    navigator.geolocation.getCurrentPosition(
+      async (position) => {
+        const { latitude, longitude } = position.coords;
+        try {
+          console.log('获取到的经纬度:', latitude, longitude);
+          // const addressInfo = await fetchAddressByCoords(latitude, longitude);
+          resolve({ latitude, longitude });
+        } catch (err) {
+          reject(err);
+        }
+      },
+      (err) => {
+        let msg = '定位失败';
+        switch (err.code) {
+          case err.PERMISSION_DENIED:
+            msg = '用户拒绝了定位请求';
+            break;
+          case err.POSITION_UNAVAILABLE:
+            msg = '位置信息不可用';
+            break;
+          case err.TIMEOUT:
+            msg = '定位请求超时';
+            break;
+        }
+        reject(new Error(msg));
+      },
+      {
+        enableHighAccuracy: true, // 高精度
+        timeout: 10000, // 超时时间 10s
+        maximumAge: 0 // 不使用缓存
+      }
+    );
+  });
+};
 
 // 判断是否已登录
 const isLoggedIn = computed(() => !!userStore.token);
@@ -93,53 +144,92 @@ const onlogout = () => {
   width: 100%;
   height: 40px;
   background-color: #efefef;
+
   .header-bos {
     width: 1200px;
     height: 100%;
-    .positioning {
-      font-weight: 400;
-      font-size: 14px;
-      color: #322b2b;
-      cursor: pointer;
-      img {
-        height: 20px;
-        width: 20px;
-        margin-right: 10px;
+    display: flex;
+    justify-content: space-between;
+
+    .header-left {
+      height: 40px;
+      .positioning {
+        font-weight: 400;
+        font-size: 12px;
+        color: #322b2b;
+        cursor: pointer;
+        img {
+          height: 18px;
+          width: 18px;
+          margin-right: 10px;
+        }
       }
     }
-    .header-box {
-      font-weight: 400;
-      font-size: 14px;
-      color: #101828;
+    .header-right {
+      display: flex;
+      .userInfo-bos {
+        min-width: 200px;
+        padding: 0 14px;
+        font-size: 12px;
+        position: relative;
+        z-index: 99;
+        margin-right: 5px;
+        overflow: hidden;
+        cursor: pointer;
+        &.open {
+          background-color: #ffffff;
+          box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.12);
+          height: 110px;
+          overflow: visible;
+          .userInfo-customer {
+            color: #e7000b;
+          }
+        }
+        .userInfo-customer {
+          height: 40px;
+          display: flex;
+          align-items: center;
+          justify-content: flex-end;
+        }
+        .userInfo-box {
+          color: #999999;
+          height: 30px;
+          line-height: 30px;
+          text-align: right;
+          cursor: pointer;
+          &:hover {
+            color: #e7000b;
+          }
+        }
+      }
       .header-text {
-        padding-right: 14px;
-        margin-right: 14px;
+        padding: 0 14px;
         position: relative;
         cursor: pointer;
+        height: 40px;
+        line-height: 40px;
+        font-size: 12px;
+
         &::after {
           content: '';
           position: absolute;
           width: 1px;
           height: 12px;
           background-color: #b7b7b7;
-          right: 0;
-          top: 4px;
+          left: 0;
+          top: 14px;
         }
+
         &.end {
-          padding-right: 0;
-          margin-right: 0;
           &::after {
             display: none;
           }
         }
+
         &.hig {
           color: #e7000b;
         }
       }
-
-      .dropdow {
-        margin-top: 2px;
-      }
     }
   }
 }

+ 2 - 1
src/layout/components/search.vue

@@ -2,7 +2,7 @@
   <!-- 搜索组件 -->
   <div class="search-bos" :style="{ 'background': meta.workbench ? '#F4F4F4' : '#ffffff' }">
     <div class="search-content">
-      <img class="logo" src="@/assets/images/head.png" alt="" />
+      <img class="logo" src="@/assets/images/head.png" alt="" @click="onPath('/')" />
       <div class="search-box">
         <div class="search-div flex-row-start">
           <div class="search-input flex-row-center">
@@ -80,6 +80,7 @@ getSearchTitle({}).then((res) => {
     border-radius: 4px;
     margin-top: 10px;
     margin-right: 30px;
+    cursor: pointer;
   }
 
   .search-box {

+ 241 - 105
src/layout/components/workbench.vue

@@ -1,41 +1,81 @@
 <template>
-  <div>
-    <aside class="layout-sidebar">
-      <div class="sidebar-section" v-for="menu in menuList" :key="menu.path">
-        <div class="section-header" @click="toggleMenu(menu.path)">
-          <el-icon><component :is="menu.icon" /></el-icon>
-          <span>{{ menu.title }}</span>
-          <el-icon class="arrow"><ArrowDown /></el-icon>
+  <div class="workbench-bos" :class="isOpen ? 'workbench-bos1' : 'workbench-bos2'">
+    <div class="workbench-box1" v-if="isOpen">
+      <div class="workbench-expand1 flex-row-start" @click="onOpen">
+        <img src="@/assets/images/layout/workbench.png" alt="" />
+        <div>收起菜单</div>
+      </div>
+      <div v-for="(item1, index1) in menuList" :key="index1" class="menu-list1">
+        <div class="menu-head1 flex-row-between">
+          <div class="menu-title1 flex-row-start" @click="toggleMenu(item1.path)">
+            <img :src="item1.icon" alt="" />
+            <div>{{ item1.title }}</div>
+          </div>
+          <el-icon v-if="openedMenus.includes(item1.path)" size="14"><ArrowDown /></el-icon>
+          <el-icon v-else size="14"><ArrowRight /></el-icon>
         </div>
-        <div class="section-items" v-show="openedMenus.includes(menu.path)">
+        <div class="menu-item" v-show="openedMenus.includes(item1.path)">
           <div
-            v-for="child in menu.children"
-            :key="child.path"
-            :class="['menu-item', { active: activeMenu === child.path }]"
-            @click="handleMenuSelect(child.path)"
+            @click="onPath(item2.path)"
+            v-for="(item2, index2) in item1.children"
+            :key="index2"
+            class="menu-box"
+            :class="{ 'menu-hig': activeMenu == item2.path }"
           >
-            {{ child.title }}
-            <el-icon class="item-arrow"><ArrowRight /></el-icon>
+            {{ item2.title }}
           </div>
         </div>
       </div>
-    </aside>
+    </div>
+    <div v-else class="workbench-box2">
+      <div class="workbench-expand2 flex-row-center" @click="onOpen">
+        <div class="menu-icon flex-row-center">
+          <img src="@/assets/images/layout/workbench.png" alt="" />
+        </div>
+      </div>
+
+      <div v-for="(item1, index1) in menuList" :key="index1" class="workbench-expand2 flex-row-center">
+        <el-popover placement="right">
+          <template #reference>
+            <div class="menu-icon flex-row-center" :class="{ 'hig': openedMenus.includes(item1.path) }">
+              <img :src="item1.icon" alt="" />
+            </div>
+          </template>
+          <div class="popover-bos">
+            <div class="popover-title">{{ item1.title }}</div>
+            <div
+              class="popover-list"
+              :class="{ 'popover-hig': activeMenu == item2.path }"
+              v-for="(item2, index2) in item1.children"
+              :key="index2"
+              @click="onPath(item2.path)"
+            >
+              {{ item2.title }}
+            </div>
+          </div>
+        </el-popover>
+      </div>
+    </div>
   </div>
 </template>
 <script setup lang="ts">
-import { ref, computed, watch, onMounted } from 'vue';
-import { useRouter, useRoute } from 'vue-router';
-import { ArrowDown, ArrowRight, RefreshRight, Van, Medal } from '@element-plus/icons-vue';
+import workbench1 from '@/assets/images/layout/workbench1.png';
+import workbench2 from '@/assets/images/layout/workbench2.png';
+import workbench3 from '@/assets/images/layout/workbench3.png';
+import workbench4 from '@/assets/images/layout/workbench4.png';
+import workbench5 from '@/assets/images/layout/workbench5.png';
+import workbench6 from '@/assets/images/layout/workbench6.png';
+import workbench7 from '@/assets/images/layout/workbench7.png';
 import { onPath } from '@/utils/siteConfig';
-
-const router = useRouter();
+const isOpen = ref(false);
+const openedMenus = ref<string[]>([]);
 const route = useRoute();
-
+const menuIndex = ref<any>(0);
 const menuList = [
   {
     path: '/enterprise',
     title: '企业账户',
-    icon: 'User',
+    icon: workbench1,
     children: [
       { path: '/enterprise/companyInfo', title: '企业信息' },
       { path: '/enterprise/messageNotice', title: '消息通知' },
@@ -51,7 +91,7 @@ const menuList = [
   {
     path: '/order',
     title: '交易管理',
-    icon: 'ShoppingCart',
+    icon: workbench2,
     children: [
       { path: '/order/orderManage', title: '订单管理' },
       { path: '/order/orderAudit', title: '审核订单' },
@@ -63,7 +103,7 @@ const menuList = [
   {
     path: '/organization',
     title: '组织管理',
-    icon: 'OfficeBuilding',
+    icon: workbench3,
     children: [
       { path: '/i', title: '个人信息' },
       { path: '/organization/deptManage', title: '部门管理' },
@@ -76,7 +116,7 @@ const menuList = [
   {
     path: '/cost',
     title: '成本管理',
-    icon: 'Money',
+    icon: workbench4,
     children: [
       { path: '/cost/itemExpense', title: '分项费用' },
       { path: '/cost/quotaControl', title: '额度控制' }
@@ -85,7 +125,7 @@ const menuList = [
   {
     path: '/reconciliation',
     title: '对账管理',
-    icon: 'Document',
+    icon: workbench5,
     children: [
       { path: '/reconciliation/billManage', title: '对账单管理' },
       { path: '/reconciliation/invoiceManage', title: '开票管理' }
@@ -94,7 +134,7 @@ const menuList = [
   {
     path: '/valueAdded',
     title: '增值服务',
-    icon: 'Service',
+    icon: workbench6,
     children: [
       { path: '/valueAdded/maintenance', title: '维保服务' },
       { path: '/valueAdded/complaint', title: '投诉与建议' }
@@ -103,7 +143,7 @@ const menuList = [
   {
     path: '/analysis',
     title: '采购分析',
-    icon: 'DataAnalysis',
+    icon: workbench7,
     children: [
       { path: '/analysis/orderAnalysis', title: '订单交易分析' },
       { path: '/analysis/purchaseDetail', title: '商品采购明细' },
@@ -114,8 +154,29 @@ const menuList = [
   }
 ];
 
-const openedMenus = ref<string[]>([]);
 const activeMenu = computed(() => route.path);
+const onOpen = () => {
+  isOpen.value = !isOpen.value;
+};
+
+onMounted(() => {
+  initOpenedMenus();
+
+  if (window.innerWidth > 1420) {
+    isOpen.value = true;
+  } else {
+    isOpen.value = false;
+  }
+  window.addEventListener('resize', handleResize);
+});
+
+const handleResize = () => {
+  if (window.innerWidth > 1420) {
+    isOpen.value = true;
+  } else {
+    isOpen.value = false;
+  }
+};
 
 // 根据当前路由自动展开对应的父级菜单
 const initOpenedMenus = () => {
@@ -130,18 +191,6 @@ const initOpenedMenus = () => {
   }
 };
 
-// 页面加载和路由变化时自动展开菜单
-onMounted(() => {
-  initOpenedMenus();
-});
-
-watch(
-  () => route.path,
-  () => {
-    initOpenedMenus();
-  }
-);
-
 const toggleMenu = (path: string) => {
   const index = openedMenus.value.indexOf(path);
   if (index > -1) {
@@ -153,89 +202,176 @@ const toggleMenu = (path: string) => {
   }
 };
 
-const handleMenuSelect = (path: string) => {
-  onPath(path);
-  // router.push(path);
-};
-
-const handleSearch = (keyword: string) => {
-  console.log('搜索:', keyword);
-  // TODO: 跳转到搜索结果页
-};
-
-const handleCartClick = () => {
-  console.log('打开采购车');
-  // TODO: 跳转到采购车页面
-};
+watch(
+  () => route.path,
+  () => {
+    initOpenedMenus();
+  }
+);
 </script>
 
 <style lang="scss" scoped>
-// 左侧菜单 - 商城风格
-.layout-sidebar {
-  width: 200px;
-  flex-shrink: 0;
-  background: #fff;
-  border-radius: 4px;
-  padding: 10px 0;
-  height: fit-content;
-  margin-right: 10px;
+.workbench-bos {
+  position: absolute;
+  top: 0;
 
-  .sidebar-section {
-    .section-header {
-      display: flex;
-      align-items: center;
-      gap: 8px;
-      padding: 12px 16px;
-      cursor: pointer;
+  //展开的
+  .workbench-box1 {
+    background: #ffffff;
+    border-radius: 10px;
+    padding: 10px 8px;
+    width: 180px;
+    .workbench-expand1 {
+      height: 42px;
+      width: 100%;
       font-size: 14px;
-      font-weight: 500;
-      color: #333;
-
-      .arrow {
-        margin-left: auto;
-        transition: transform 0.2s;
-      }
+      color: #1d2129;
+      padding-left: 12px;
+      cursor: pointer;
       &:hover {
         color: #e60012;
       }
+      img {
+        height: 16px;
+        width: 16px;
+        margin-right: 8px;
+      }
     }
-
-    .section-items {
-      .menu-item {
-        display: flex;
-        align-items: center;
-        justify-content: space-between;
-        padding: 10px 16px 10px 40px;
-        font-size: 13px;
-        color: #666;
+    .menu-list1 {
+      width: calc(100% - 24px);
+      border-bottom: 1px #e5e6eb solid;
+      margin: 0 12px;
+      &:nth-last-child(1) {
+        border-bottom: none;
+      }
+      .menu-head1 {
+        height: 54px;
+        width: 100%;
+        color: #1d2129;
         cursor: pointer;
-        transition: all 0.2s;
-
-        .item-arrow {
-          opacity: 0;
+        &:hover {
           color: #e60012;
         }
+        .menu-title1 {
+          font-size: 14px;
 
-        &:hover {
-          color: #e60012;
-          background: #fff5f5;
-          .item-arrow {
-            opacity: 1;
+          img {
+            height: 16px;
+            width: 16px;
+            margin-right: 8px;
           }
         }
-
-        &.active {
-          color: #e60012;
-          background: #fff5f5;
-          font-weight: 500;
-          border-left: 3px solid #e60012;
-          padding-left: 37px;
-          .item-arrow {
-            opacity: 1;
+      }
+      .menu-item {
+        padding-bottom: 5px;
+        .menu-box {
+          width: 100%;
+          height: 36px;
+          border-radius: 3px;
+          font-size: 13px;
+          color: #4e5969;
+          padding-left: 12px;
+          line-height: 36px;
+          cursor: pointer;
+          &.menu-hig {
+            background: #f7f8fa;
+            color: #e60012;
+          }
+          &:hover {
+            color: #e60012;
           }
         }
       }
     }
   }
+
+  //收起的
+  .workbench-box2 {
+    background: #ffffff;
+    border-radius: 10px;
+    padding: 10px 8px;
+    width: 50px;
+    .workbench-expand2 {
+      width: 34px;
+      height: 36px;
+      cursor: pointer;
+      position: relative;
+      .menu-icon {
+        width: 24px;
+        height: 24px;
+        &.hig {
+          background-color: #ffe8e8;
+        }
+        img {
+          height: 16px;
+          width: 16px;
+        }
+      }
+
+      .menu-open {
+        position: absolute;
+        right: -168px;
+        top: 0;
+        width: 148px;
+        background-color: #ffffff;
+        z-index: 99;
+        padding: 10px 18px;
+        border-radius: 10px;
+      }
+    }
+    // .workbench-expand2 {
+    //   width: 24px;
+    //   height: 24px;
+    //   cursor: pointer;
+    //   margin: 16px auto;
+    //   position: relative;
+    //   &:hover {
+    //     background-color: #ffe8e8;
+    //   }
+    //   &::after {
+    //     content: '';
+    //     width: 10px;
+    //     height: 1px;
+    //     background-color: #e5e6eb;
+    //     position: absolute;
+    //     left: 7px;
+    //     bottom: -10px;
+    //   }
+    //   img {
+    //     height: 16px;
+    //     width: 16px;
+    //   }
+    // }
+  }
+  &.workbench-bos1 {
+    left: -200px;
+  }
+  &.workbench-bos2 {
+    left: -70px;
+  }
+}
+
+.popover-bos {
+  .popover-title {
+    font-size: 12px;
+    color: #9095a0;
+    margin-bottom: 7px;
+    padding-left: 4px;
+  }
+  .popover-list {
+    width: 120px;
+    height: 32px;
+    font-size: 14px;
+    color: #1c2c49;
+    line-height: 32px;
+    padding-left: 4px;
+    cursor: pointer;
+    &:hover {
+      color: #e60012;
+    }
+    &.popover-hig {
+      background: #ffe8e8;
+    }
+  }
 }
 </style>

+ 6 - 1
src/layout/index.vue

@@ -29,12 +29,17 @@ watch(route, () => {
 @use '@/assets/styles/variables.module.scss' as *;
 
 .app-wrapper {
-  min-height: 100%;
+  min-height: 100vh;
   width: 100%;
+  min-width: 1350px;
   background: #f4f4f4;
+  display: flex;
+  flex-direction: column;
 
   .pages-bos {
     display: flex;
+    flex: 1;
+    position: relative;
 
     &.pages-bos1 {
       width: 1200px;

+ 55 - 28
src/permission.ts

@@ -29,32 +29,26 @@ const whiteList = [
   '/item',
   '/breg',
   '/greg',
-  '/diy',
-  '/theme'
+  '/theme',
+  '/indexDiy',
+  '/indexMroDiy',
+  '/indexFuliDiy',
+  '/indexDataDiy'
 ];
 
 const isWhiteList = (path: string) => {
   return whiteList.some((pattern) => isPathMatch(pattern, path));
 };
 
-// function getMainSiteUrl(path: string) {
-//   if (import.meta.env.PROD) {
-//     return `https://index.xiaoluwebsite.xyz${path}`;
-//   } else {
-//     const devPort = window.location.port || import.meta.env.VITE_APP_PORT;
-//     return `https://index.xiaoluwebsite.xyz:${devPort}${path}`;
-//   }
-// }
-
-// 根据 isDiy 字段决定首页路径
-function getDomainHomePath(site: string, station: ReturnType<typeof stationStore>) {
+// 根据配置决定首页路径
+function getDomainHomePath(site: string, station: ReturnType<typeof stationStore>, toPath: string) {
   const allowedPaths = SITE_ROUTES[site] || [];
+
+  // 原有的 /indexData 和 /indexDataDiy 逻辑保持不变
   const hasIndexData = allowedPaths.includes('/indexData');
-  const hasDiy = allowedPaths.includes('/diy');
-  const hasIndex = allowedPaths.includes('/index');
+  const hasIndexDataDiy = allowedPaths.includes('/indexDataDiy');
 
   if (station.stationData && Object.keys(station.stationData).length > 0) {
-    // 兼容:stationData.data.isDiy 或 stationData.isDiy
     const data = station.stationData.data || station.stationData;
     const isDiy = data?.isDiy;
 
@@ -63,14 +57,42 @@ function getDomainHomePath(site: string, station: ReturnType<typeof stationStore
         return '/indexData';
       }
     } else if (isDiy !== undefined && isDiy !== null) {
-      if (hasDiy) {
-        return '/diy';
+      if (hasIndexDataDiy) {
+        return '/indexDataDiy';
       }
     }
   }
 
-  if (hasIndex) {
-    return '/index';
+  // 新增:根据 diyConfig 配置判断 /index、/indexMro、/indexFuli
+  const diyConfig = station.diyState || [];
+
+  // 处理 / 或 /index
+  if (toPath === '/' || toPath === '/index') {
+    const platformDiy = diyConfig.find((item: any) => item.configKey === 'platormDiy');
+    if (platformDiy?.value === '1' && allowedPaths.includes('/indexDiy')) {
+      return '/indexDiy';
+    }
+    if (allowedPaths.includes('/index')) {
+      return '/index';
+    }
+  }
+
+  // 处理 /indexMro
+  if (toPath === '/indexMro') {
+    const industrialDiy = diyConfig.find((item: any) => item.configKey === 'industrialDiy');
+    if (industrialDiy?.value === '1' && allowedPaths.includes('/indexMroDiy')) {
+      return '/indexMroDiy';
+    }
+    return '/indexMro';
+  }
+
+  // 处理 /indexFuli
+  if (toPath === '/indexFuli') {
+    const fuliDiy = diyConfig.find((item: any) => item.configKey === 'fuliDiy');
+    if (fuliDiy?.value === '1' && allowedPaths.includes('/indexFuliDiy')) {
+      return '/indexFuliDiy';
+    }
+    return '/indexFuli';
   }
 
   return allowedPaths[0] || '/';
@@ -111,12 +133,10 @@ router.beforeEach(async (to, from, next) => {
       return;
     }
 
-    // 修复:有 token 时请求购物车和站点数据
+    // 有 token 时请求购物车和站点数据
     if (token) {
       try {
-        // 获取购物车数量
         cart.onCartCount();
-        // 获取站点数据
         await station.onstation();
       } catch (error) {
         console.error('获取站点数据失败:', error);
@@ -124,11 +144,18 @@ router.beforeEach(async (to, from, next) => {
     }
   }
 
+  // 无论是否有 token,都获取 DIY 配置数据(新接口无需登录)
+  try {
+    await station.onDiyState();
+  } catch (error) {
+    console.error('获取 DIY 配置失败:', error);
+  }
+
   // 需求四:多域名下检查路径权限
   if (isMultiDomain) {
-    const homePaths = ['/', '/index', '/indexData', '/diy'];
+    const homePaths = ['/', '/index', '/indexData', '/indexDataDiy', '/indexMro', '/indexFuli'];
     if (homePaths.includes(to.path)) {
-      const homePath = getDomainHomePath(site, station);
+      const homePath = getDomainHomePath(site, station, to.path);
       if (to.path !== homePath) {
         doRedirect(homePath, next, isMultiDomain);
         NProgress.done();
@@ -138,16 +165,16 @@ router.beforeEach(async (to, from, next) => {
 
     if (!allowedPaths.includes(to.path)) {
       console.warn(`[${site}] 禁止访问 ${to.path}`);
-      const homePath = getDomainHomePath(site, station);
+      const homePath = getDomainHomePath(site, station, to.path);
       doRedirect(homePath, next, isMultiDomain);
       NProgress.done();
       return;
     }
   } else {
     // 单域名下首页处理
-    const homePaths = ['/', '/index', '/indexData', '/diy'];
+    const homePaths = ['/', '/index', '/indexData', '/indexDataDiy', '/indexMro', '/indexFuli'];
     if (homePaths.includes(to.path)) {
-      const homePath = getDomainHomePath(site, station);
+      const homePath = getDomainHomePath(site, station, to.path);
       if (to.path !== homePath) {
         doRedirect(homePath, next, isMultiDomain);
         NProgress.done();

+ 28 - 10
src/router/index.ts

@@ -68,6 +68,12 @@ export const constantRoutes: RouteRecordRaw[] = [
         name: 'Index',
         meta: { title: '优易365', affix: true, nav: true }
       },
+      {
+        path: '/indexDiy',
+        component: () => import('@/views/home/indexDiy.vue'),
+        name: 'IndexDiy',
+        meta: { title: '优易365Diy', diy: true, search: 'hide' }
+      },
       {
         path: '/indexB',
         component: () => import('@/views/home/index-b.vue'),
@@ -80,6 +86,12 @@ export const constantRoutes: RouteRecordRaw[] = [
         name: 'IndexMro',
         meta: { title: '工业品商城', affix: true, nav: true }
       },
+      {
+        path: '/indexMroDiy',
+        component: () => import('@/views/home/index-mroDiy.vue'),
+        name: 'IndexMroDiy',
+        meta: { title: '工业品商城Diy', diy: true, search: 'hide' }
+      },
       {
         path: '/indexFuli',
         component: () => import('@/views/home/index-fuli.vue'),
@@ -87,16 +99,10 @@ export const constantRoutes: RouteRecordRaw[] = [
         meta: { title: '福礼商城', icon: 'dashboard', affix: true, nav: true }
       },
       {
-        path: '/diy',
-        component: () => import('@/views/home/diy.vue'),
-        name: 'IndexDiy',
-        meta: { title: 'Diy商城', diy: true, search: 'hide' }
-      },
-      {
-        path: '/theme',
-        component: () => import('@/views/home/theme.vue'),
-        name: 'IndexTheme',
-        meta: { title: '详情', icon: 'dashboard', affix: true, nav: true }
+        path: '/indexFuliDiy',
+        component: () => import('@/views/home/index-fuliDiy.vue'),
+        name: 'IndexFuliDiy',
+        meta: { title: '福礼商城Diy', diy: true, search: 'hide' }
       },
       {
         path: '/indexData',
@@ -104,6 +110,18 @@ export const constantRoutes: RouteRecordRaw[] = [
         name: 'indexData',
         meta: { title: '大客户站点', icon: 'dashboard', affix: true, nav: true }
       },
+      {
+        path: '/indexDataDiy',
+        component: () => import('@/views/home/index-dataDiy.vue'),
+        name: 'IndexDataDiy',
+        meta: { title: '大客户站点Diy', diy: true, search: 'hide' }
+      },
+      {
+        path: '/theme',
+        component: () => import('@/views/home/theme.vue'),
+        name: 'IndexTheme',
+        meta: { title: '详情', icon: 'dashboard', affix: true, nav: true }
+      },
       {
         path: '/reg',
         component: () => import('@/views/reg/index.vue'),

+ 11 - 1
src/store/modules/station.ts

@@ -1,7 +1,9 @@
 import { getSiteAddress } from '@/api/home/index-data';
+import { getIsUseDiy } from '@/api/home/diy';
 
 export const stationStore = defineStore('station', () => {
   const stationData = ref<any>({});
+  const diyState = ref<any>([]);
 
   const onstation = async () => {
     const res = await getSiteAddress({});
@@ -9,8 +11,16 @@ export const stationStore = defineStore('station', () => {
     return res.data;
   };
 
+  const onDiyState = async () => {
+    const res = await getIsUseDiy({});
+    diyState.value = res.data;
+    return res.data;
+  };
+
   return {
     stationData,
-    onstation
+    onstation,
+    onDiyState,
+    diyState
   };
 });

+ 4 - 17
src/store/modules/user.ts

@@ -7,6 +7,7 @@ import { defineStore } from 'pinia';
 import { ref } from 'vue';
 
 export const useUserStore = defineStore('user', () => {
+  const userInfo = ref<any>({});
   const token = ref(getToken());
   const name = ref('');
   const nickname = ref('');
@@ -36,22 +37,7 @@ export const useUserStore = defineStore('user', () => {
   const getInfo = async (): Promise<void> => {
     const [err, res] = await to(getUserInfo());
     if (res) {
-      const data = res.data;
-      const user = data.user;
-      const profile = user.avatar == '' || user.avatar == null ? defAva : user.avatar;
-
-      if (data.roles && data.roles.length > 0) {
-        // 验证返回的roles是否是一个非空数组
-        roles.value = data.roles;
-        permissions.value = data.permissions;
-      } else {
-        roles.value = ['ROLE_DEFAULT'];
-      }
-      name.value = user.userName;
-      nickname.value = user.nickName;
-      avatar.value = profile;
-      userId.value = user.userId;
-      tenantId.value = user.tenantId;
+      userInfo.value = res.data;
       return Promise.resolve();
     }
     return Promise.reject(err);
@@ -81,6 +67,7 @@ export const useUserStore = defineStore('user', () => {
     login,
     getInfo,
     logout,
-    setAvatar
+    setAvatar,
+    userInfo
   };
 });

+ 1 - 2
src/types/components.d.ts

@@ -66,12 +66,11 @@ declare module 'vue' {
     ElTree: typeof import('element-plus/es')['ElTree']
     ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect']
     ElUpload: typeof import('element-plus/es')['ElUpload']
-    EmptyState: typeof import('./../components/EmptyState/index.vue')['default']
     FileUpload: typeof import('./../components/FileUpload/index.vue')['default']
     FlowChart: typeof import('./../components/Process/flowChart.vue')['default']
     FlowChartImg: typeof import('./../components/Process/flowChartImg.vue')['default']
     Hamburger: typeof import('./../components/Hamburger/index.vue')['default']
-    HeaderBar: typeof import('./../components/HeaderBar/index.vue')['default']
+    Icon: typeof import('./../components/icon/index.vue')['default']
     IconSelect: typeof import('./../components/IconSelect/index.vue')['default']
     IFrame: typeof import('./../components/iFrame/index.vue')['default']
     ImagePreview: typeof import('./../components/ImagePreview/index.vue')['default']

+ 4 - 5
src/utils/siteConfig.ts

@@ -31,10 +31,10 @@ const REVERSE_DOMAIN_MAP: Record<string, string> = Object.entries(DOMAIN_MAP).re
 
 // 每个站点允许的路由 (保持不变)
 export const SITE_ROUTES: Record<any, string[]> = {
-  www: ['/', '/index', '/indexData', '/theme', '/diy'], //优易365主站
+  www: ['/', '/index', '/indexDiy', '/indexData', '/indexDataDiy', '/theme'], //优易365主站
   b: ['/indexB'], //企业购商城
-  mro: ['/indexMro'], //工业品商城
-  fuli: ['/indexFuli'], //福礼商城
+  mro: ['/indexMro', '/indexMroDiy'], //工业品商城
+  fuli: ['/indexFuli', '/indexFuliDiy'], //福礼商城
   reg: ['/reg'], //个人注册
   breg: ['/breg'], //企业注册
   greg: ['/greg'], //供应商注册
@@ -102,7 +102,7 @@ export function getCurrentSite(): any {
 
   // 使用环境变量配置的域名映射
   if (host === 'localhost') return 'www'; // 兼容未配hosts的情况
-  
+
   // 从反向映射中查找站点
   const site = REVERSE_DOMAIN_MAP[host];
   if (site) return site;
@@ -133,7 +133,6 @@ export function getSiteByPath(path: string): any | null {
 import router from '@/router';
 export function onPath(path: string) {
   console.log('[跨站跳转]', path);
-  // return
   if (import.meta.env.VITE_DOMAIN_NAME == 'true') {
     const targetSite = getSiteByPath(path);
 

+ 10 - 1
src/views/breg/index.vue

@@ -125,7 +125,8 @@
       </div>
       <template #footer>
         <span class="dialog-footer">
-          <el-button type="primary" @click="dialogVisible = false">确定</el-button>
+          <el-button type="primary" @click="onAgree">同意</el-button>
+          <el-button @click="dialogVisible = false">取消</el-button>
         </span>
       </template>
     </el-dialog>
@@ -340,14 +341,22 @@ onUnmounted(() => {
 const openDialog = () => {
   dialogVisible.value = true;
 };
+
+const onAgree = () => {
+  radio.value = true;
+  dialogVisible.value = false;
+};
 </script>
 
 <style lang="scss" scoped>
 .register-pages {
   width: 100%;
   background-color: #ffffff;
+  display: flex;
+  flex-direction: column;
 
   .register-bos {
+    flex: 1;
     width: 1200px;
     margin: 0 auto;
     padding-top: 20px;

+ 44 - 30
src/views/cart/index.vue

@@ -36,9 +36,15 @@
         <el-table-column label="单价" width="130">
           <template #default="scope"> ¥{{ scope.row.memberPrice }} </template>
         </el-table-column>
+        <!-- @blur="(res) => handleChange(res, scope.row)" -->
         <el-table-column label="数量" width="200">
           <template #default="scope">
-            <el-input-number v-model="scope.row.productNum" :min="1" :max="scope.row.allStock" @change="(res) => handleChange(res, scope.row)" />
+            <el-input-number
+              v-model="scope.row.productNum"
+              :min="scope.row.minOrderQuantity"
+              :max="scope.row.allStock"
+              @change="handleChange(scope.row)"
+            />
           </template>
         </el-table-column>
         <el-table-column label="小计" width="140">
@@ -47,10 +53,10 @@
         <el-table-column label="操作">
           <template #default="scope">
             <div>
-              <el-button @click="editCollection(scope.row)" link>{{ scope.row.isCollect == 1 ? '取消收藏' : '移入收藏' }} </el-button>
+              <el-button @click="editCollection(scope, 1)" link>{{ scope.row.isCollect == 1 ? '取消收藏' : '移入收藏' }} </el-button>
             </div>
             <div>
-              <el-button link @click="onDel(scope.row)"> 删除 </el-button>
+              <el-button link @click="onDel(scope, 1)"> 删除 </el-button>
             </div>
           </template>
         </el-table-column>
@@ -78,7 +84,7 @@
                 <div class="text2">
                   <span>单位:{{ scope.row.unitName }}</span>
                 </div>
-                <div class="text3">当前商品库存不足,当前库存量:0</div>
+                <!-- <div class="text3">当前商品库存不足,当前库存量:0</div> -->
               </div>
             </div>
           </template>
@@ -97,10 +103,10 @@
         <el-table-column label="操作">
           <template #default="scope">
             <div>
-              <el-button @click="editCollection(scope.row)" link>{{ scope.row.isCollect == 1 ? '取消收藏' : '移入收藏' }} </el-button>
+              <el-button @click="editCollection(scope, 2)" link>{{ scope.row.isCollect == 1 ? '取消收藏' : '移入收藏' }} </el-button>
             </div>
             <div>
-              <el-button link @click="onDel(scope.row)"> 删除 </el-button>
+              <el-button link @click="onDel(scope, 2)"> 删除 </el-button>
             </div>
           </template>
         </el-table-column>
@@ -172,7 +178,8 @@ import {
   cancelProductCollect,
   addProductCollect,
   favoritesList,
-  exportProductShoppingCart
+  exportProductShoppingCart,
+  updateProductShoppingCart
 } from '@/api/goods/index';
 import FileSaver from 'file-saver';
 import { onPath } from '@/utils/siteConfig';
@@ -182,15 +189,18 @@ onMounted(() => {
 });
 
 const getInfo = () => {
-  shoppingCartList({}).then((res) => {
+  shoppingCartList({
+    pageNum: 1,
+    pageSize: 999
+  }).then((res) => {
     if (res.code == 200) {
       tableData.value = [];
       noTableData.value = [];
       if (res.rows && res.rows.length > 0) {
         res.rows.forEach((item: any) => {
           item.allStock = Number(item.totalInventory || 0) + Number(item.nowInventory || 0) + Number(item.virtualInventory || 0);
-          // item.allStock = 8888;
-          if (item.productStatus == 1 && item.allStock > 0) {
+          item.minOrderQuantity = Number(item.minOrderQuantity || 1);
+          if (item.productStatus == 1) {
             tableData.value.push(item);
           } else {
             noTableData.value.push(item);
@@ -201,12 +211,6 @@ const getInfo = () => {
   });
 };
 
-const handleChange = (val: any, row: any) => {
-  const numberVal = Number(val);
-  const step = row.minOrderQuantity || 1;
-  row.productNum = Math.ceil(numberVal / step) * step;
-};
-
 //购物车选中
 const handleSelectionChange1 = (val: any) => {
   selectedList.value = val;
@@ -223,16 +227,20 @@ const handleSelectAll = (val: any) => {
 
 import { cartStore } from '@/store/modules/cart';
 const cart = cartStore();
-const onDel = (row: any) => {
+const onDel = (scope: any, type: any) => {
   ElMessageBox.confirm(`确定要删除吗?`, '提示', {
     confirmButtonText: '确定',
     cancelButtonText: '取消',
     type: 'warning'
   }).then(() => {
-    deleteProductShoppingCart(row.shoppingCartId).then((res) => {
+    deleteProductShoppingCart(scope.row.shoppingCartId).then((res) => {
       if (res.code == 200) {
         ElMessage.success('删除成功');
-        getInfo();
+        if (type == 1) {
+          tableData.value.splice(scope.$index, 1);
+        } else {
+          noTableData.value.splice(scope.$index, 1);
+        }
         cart.onCartCount();
       }
     });
@@ -259,21 +267,21 @@ const onMoney = computed(() => {
 });
 
 //修改收藏
-const editCollection = (row: any) => {
-  if (row.isCollect == 1) {
+const editCollection = (scope: any, type: any) => {
+  if (scope.row.isCollect == 1) {
     dialogVisible.value = true;
-    favoritesList(row.id).then((res) => {
+    favoritesList(scope.row.id).then((res) => {
       if (res.code == 200) {
         if (res.rows.length > 0) {
           radio.value = res.rows[0].id;
         }
         favorites.value = res.rows;
-        radioRow.value = row;
+        radioRow.value = scope.row;
       }
     });
   } else {
     // 添加
-    addProductCollect({ productId: row.id }).then((res) => {
+    addProductCollect({ productId: scope.row.id }).then((res) => {
       if (res.code == 200) {
         getInfo();
       }
@@ -293,12 +301,18 @@ const onCancel = () => {
 
 // 导出订单
 const onExport = () => {
-  exportProductShoppingCart().then((res: any) => {
-    const blob = new Blob([res], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
-    FileSaver.saveAs(blob, '购物车商品.xlsx');
-  }).catch(() => {
-    ElMessage.error('导出失败,请稍后重试');
-  });
+  exportProductShoppingCart()
+    .then((res: any) => {
+      const blob = new Blob([res], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
+      FileSaver.saveAs(blob, '购物车商品.xlsx');
+    })
+    .catch(() => {
+      ElMessage.error('导出失败,请稍后重试');
+    });
+};
+
+const handleChange = (row: any) => {
+  updateProductShoppingCart({ productId: row.id, productNum: row.productNum }).then((res) => {});
 };
 </script>
 

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 32 - 3
src/views/greg/index.vue


+ 0 - 35
src/views/home/diy copy.vue

@@ -1,35 +0,0 @@
-<template>
-  <div class="pay-pages"></div>
-</template>
-
-<script setup lang="ts">
-import { getAnnouncementPage, getDiyProductPage, getServiceCaseList, getPlatformIndexDiyPcPage } from '@/api/home/diy';
-
-getAnnouncementPage({
-  pageNum: 1,
-  pageSize: 10,
-  ids: '1,2,3'
-}).then((res) => {
-  if (res.code == 200) {
-    // carouselList.value = res.data;
-  }
-});
-getDiyProductPage({ pageNum: 1, pageSize: 10, ids: '434643,434645' }).then((res) => {
-  if (res.code == 200) {
-    // carouselList.value = res.data;
-  }
-});
-getServiceCaseList({ pageNum: 1, pageSize: 10, ids: '1031,1032' }).then((res) => {
-  if (res.code == 200) {
-    // carouselList.value = res.data;
-  }
-});
-
-getPlatformIndexDiyPcPage({}).then((res) => {
-  if (res.code == 200) {
-    // carouselList.value = res.data;
-  }
-});
-</script>
-
-<style lang="scss" scoped></style>

+ 7 - 1
src/views/home/diy.vue

@@ -10,6 +10,11 @@
 import { getBigCustomerPlatformIndexDiyPcPage } from '@/api/home/diy';
 import { loadDiyComponents, getComponentGroups } from '@/views/home/pccomponents/index';
 import { stationStore } from '@/store/modules/station';
+
+const props = defineProps<{
+  dataInfo?: any;
+}>();
+
 const station = stationStore();
 const componentList = ref<any>([]);
 const collapse = ref<any>([]);
@@ -18,7 +23,8 @@ const query = route.query;
 const formData = ref<any>({});
 
 onMounted(() => {
-  loadComponents();
+  console.log('props', props.dataInfo);
+  // loadComponents();
 });
 
 // 加载组件

+ 27 - 0
src/views/home/index-dataDiy.vue

@@ -0,0 +1,27 @@
+<template>
+  <div class="w100%">
+    <diyIndex v-if="dataInfo && dataInfo.isHome" :dataInfo="dataInfo"></diyIndex>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { getBigCustomerPlatformIndexDiyPcPage } from '@/api/home/diy';
+import diyIndex from '@/views/home/pccomponents/index.vue';
+import { stationStore } from '@/store/modules/station';
+const dataInfo = ref<any>(null);
+const station = stationStore();
+onMounted(() => {
+  loadComponents();
+});
+
+// 加载组件
+const loadComponents = async () => {
+  getBigCustomerPlatformIndexDiyPcPage({ siteId: station.stationData.id }).then((res) => {
+    if (res.code == 200) {
+      dataInfo.value = res.data;
+    }
+  });
+};
+</script>
+
+<style lang="scss" scoped></style>

+ 19 - 0
src/views/home/index-fuliDiy.vue

@@ -0,0 +1,19 @@
+<template>
+  <div class="w100%">
+    <diyIndex v-if="dataInfo && dataInfo.isHome" :dataInfo="dataInfo"></diyIndex>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { getIndexDiyPcPage } from '@/api/home/diy';
+import diyIndex from '@/views/home/pccomponents/index.vue';
+const dataInfo = ref<any>(null);
+
+getIndexDiyPcPage({ type: 3 }).then((res) => {
+  if (res.code == 200) {
+    dataInfo.value = res.data;
+  }
+});
+</script>
+
+<style lang="scss" scoped></style>

+ 19 - 0
src/views/home/index-mroDiy.vue

@@ -0,0 +1,19 @@
+<template>
+  <div class="w100%">
+    <diyIndex v-if="dataInfo && dataInfo.isHome" :dataInfo="dataInfo"></diyIndex>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { getIndexDiyPcPage } from '@/api/home/diy';
+import diyIndex from '@/views/home/pccomponents/index.vue';
+const dataInfo = ref<any>(null);
+
+getIndexDiyPcPage({ type: 2 }).then((res) => {
+  if (res.code == 200) {
+    dataInfo.value = res.data;
+  }
+});
+</script>
+
+<style lang="scss" scoped></style>

+ 4 - 4
src/views/home/index.vue

@@ -58,11 +58,11 @@
             </div>
             <div class="flex-1 flex-column-center">
               <div>待发货</div>
-              <div class="order-num">{{ countData.pendingShipmentCount || 0}}</div>
+              <div class="order-num">{{ countData.pendingShipmentCount || 0 }}</div>
             </div>
             <div class="flex-1 flex-column-center">
               <div>待收货</div>
-              <div class="order-num">{{ countData.pendingReceiptCount || 0}}</div>
+              <div class="order-num">{{ countData.pendingReceiptCount || 0 }}</div>
             </div>
           </div>
         </div>
@@ -351,7 +351,7 @@ import profile from '@/assets/images/profile.jpg';
 import { onPath } from '@/utils/siteConfig';
 import { getToken } from '@/utils/auth';
 import { getInfo } from '@/api/login';
-import { getPlatformIndexDiyPcPage } from '@/api/home/diy';
+import { getIndexDiyPcPage, getIsUseDiy } from '@/api/home/diy';
 import {
   getProductCategoryTree,
   getHomeAdList,
@@ -406,7 +406,7 @@ const countData = ref<any>({});
 const homeList = ref<any>([]);
 const router = useRouter();
 
-getPlatformIndexDiyPcPage({}).then((res) => {
+getIndexDiyPcPage({ type: 1 }).then((res) => {
   if (res.code == 200) {
   }
 });

+ 19 - 0
src/views/home/indexDiy.vue

@@ -0,0 +1,19 @@
+<template>
+  <div class="w100%">
+    <diyIndex v-if="dataInfo && dataInfo.isHome" :dataInfo="dataInfo"></diyIndex>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { getIndexDiyPcPage } from '@/api/home/diy';
+import diyIndex from '@/views/home/pccomponents/index.vue';
+const dataInfo = ref<any>(null);
+
+getIndexDiyPcPage({ type: 1 }).then((res) => {
+  if (res.code == 200) {
+    dataInfo.value = res.data;
+  }
+});
+</script>
+
+<style lang="scss" scoped></style>

+ 63 - 41
src/views/home/pccomponents/index.ts

@@ -35,12 +35,13 @@ export const componentImportConfigs: any = [
     enabled: true,
     ...createComponentMap('imageCube')
   },
-  // {
-  //   name: '活动魔方',
-  //   icon: 'iconfont iconmofangpc',
-  //   enabled: true,
-  //   id: 5
-  // },
+  {
+    name: '活动魔方',
+    icon: 'iconfont iconmofangpc',
+    enabled: true,
+    id: 5,
+    ...createComponentMap('activity')
+  },
   {
     name: '轮播图',
     icon: 'iconfont icona-tupianzhanbopc302',
@@ -69,41 +70,62 @@ export const componentImportConfigs: any = [
     id: 9,
     ...createComponentMap('advert')
   },
-  // {
-  //   name: '楼层组件',
-  //   icon: 'iconfont iconshangpinliebiaopc',
-  //   enabled: true,
-  //   id: 10,
-  //   ...createComponentMap('floor')
-  // },
-  // {
-  //   name: '商品组件',
-  //   icon: 'iconfont icona-shangpintuijianpc30',
-  //   enabled: true,
-  //   id: 11,
-  //   ...createComponentMap('goods')
-  // },
-  // {
-  //   name: '多商品组',
-  //   icon: 'iconfont iconduoshangpinzupc',
-  //   enabled: true,
-  //   id: 12,
-  //   ...createComponentMap('goodsList')
-  // },
-  // {
-  //   name: '发现组件',
-  //   icon: 'iconfont iconjifenshangpinpc',
-  //   enabled: true,
-  //   id: 13,
-  //   ...createComponentMap('discover')
-  // },
-  // {
-  //   name: '热区',
-  //   icon: 'iconfont iconrequpc',
-  //   enabled: true,
-  //   id: 14,
-  //   ...createComponentMap('hot')
-  // }
+  {
+    name: '楼层组件',
+    icon: 'iconfont iconshangpinliebiaopc',
+    enabled: true,
+    id: 10,
+    ...createComponentMap('floor')
+  },
+  {
+    name: '商品组件',
+    icon: 'iconfont icona-shangpintuijianpc30',
+    enabled: true,
+    id: 11,
+    ...createComponentMap('goods')
+  },
+  {
+    name: '多商品组',
+    icon: 'iconfont iconduoshangpinzupc',
+    enabled: true,
+    id: 12,
+    ...createComponentMap('goodsList')
+  },
+  {
+    name: '发现组件',
+    icon: 'iconfont iconjifenshangpinpc',
+    enabled: true,
+    id: 13,
+    ...createComponentMap('discover')
+  },
+  {
+    name: '热区',
+    icon: 'iconfont iconrequpc',
+    enabled: true,
+    id: 14,
+    ...createComponentMap('hot')
+  },
+  {
+    name: '富文本',
+    icon: 'iconfont iconfuwenbenpc',
+    enabled: true,
+    id: 15,
+    ...createComponentMap('editordiy')
+  },
+  {
+    name: '辅助空白',
+    icon: 'iconfont iconfuzhukongbaipc',
+    enabled: true,
+    id: 16,
+    ...createComponentMap('blank')
+  },
+  {
+    name: '辅助线',
+    icon: 'iconfont iconfuzhuxianpc',
+    enabled: true,
+    id: 17,
+    ...createComponentMap('border')
+  }
 ];
 
 /**

+ 57 - 0
src/views/home/pccomponents/index.vue

@@ -0,0 +1,57 @@
+<template>
+  <div class="pcdiys-pages" :style="{ backgroundColor: componentList.backgroundColor }">
+    <div v-for="(item, index) in componentList" :key="index">
+      <component :is="item.components" :key="item.itemKey" :index="index" :row="item"></component>
+    </div>
+  </div>
+</template>
+
+<script setup name="Index" lang="ts">
+import { loadDiyComponents, getComponentGroups } from '@/views/home/pccomponents/index';
+const componentList = ref<any>([]);
+const collapse = ref<any>([]);
+
+const props = defineProps<{
+  dataInfo?: any;
+}>();
+
+onMounted(() => {
+  loadComponents();
+});
+
+// 加载组件
+const loadComponents = async () => {
+  const components = await loadDiyComponents();
+  collapse.value = getComponentGroups(components);
+  document.documentElement.style.setProperty('--hover-color', props.dataInfo.hoverColor ? props.dataInfo.hoverColor : '#E7000B');
+  const datas = JSON.parse(props.dataInfo.property);
+  collapse.value.forEach((item1: any) => {
+    datas.forEach((item2: any) => {
+      if (item1.id == item2.fid) {
+        item1.list.forEach((item3: any) => {
+          if (item2.id == item3.id) {
+            item2.components = item3.components;
+          }
+        });
+      }
+    });
+  });
+  componentList.value = datas;
+};
+</script>
+
+<style lang="scss" scoped>
+.pcdiys-pages {
+  background-color: #f2f2f2;
+  width: 100%;
+  :deep(.hover-color) {
+    cursor: pointer;
+    &:hover {
+      color: var(--hover-color) !important;
+      .zi-hover {
+        color: var(--hover-color) !important;
+      }
+    }
+  }
+}
+</style>

+ 287 - 94
src/views/home/pccomponents/pages/activity.vue

@@ -1,57 +1,92 @@
 <template>
-  <div class="pcPages">
-    <div class="carousel-bos" :style="warpCss" v-if="componentData.styleType == 3">
-      <el-carousel :height="270 * componentData.count + (componentData.count == 2 ? 10 : 0) + 'px'" :autoplay="false" arrow="always">
-        <el-carousel-item v-for="(item1, index1) in dataList" :key="index1" class="w100% h100%">
-          <div class="carousel-list">
-            <div v-for="(item, index) in item1" :key="index" class="data-list flex-column-between" :style="boxCss">
-              <el-image
-                class="img"
-                :src="item.imageUrl ? item.imageUrl : figure"
-                :fit="item.imgType == 1 ? 'fill' : item.imgType == 2 ? 'contain' : 'cover'"
-                :style="componentData.imageRadius ? { borderRadius: componentData.imageRadius + 'px' } : {}"
-              />
-              <div :style="titleCss" class="title">{{ item.title || '' }}</div>
-              <div :style="subtitleCss" class="mt-[2px] mb-[12px] subtitle ellipsis">{{ item.subtitle || '' }}</div>
-            </div>
-          </div>
-        </el-carousel-item>
-      </el-carousel>
-    </div>
-    <div v-else :style="warpCss" class="data-bos">
-      <div v-for="(item, index) in componentData.navlList" :key="index" class="data-list flex-column-between" :style="boxCss">
+  <div class="pcPages" :style="warpCss">
+    <div :style="boxCss">
+      <div class="head-bos flex-row-start" :style="radiusCss">
         <el-image
-          class="img"
-          :src="item.imageUrl ? item.imageUrl : figure"
-          :fit="item.imgType == 1 ? 'fill' : item.imgType == 2 ? 'contain' : 'cover'"
-          :style="componentData.imageRadius ? { borderRadius: componentData.imageRadius + 'px' } : {}"
+          v-if="componentData.styleType == 4"
+          class="head-img"
+          :src="componentData.titleImg ? componentData.titleImg : figure"
+          :fit="componentData.titleImg ? (componentData.titleImgType == 1 ? 'fill' : componentData.titleImgType == 2 ? 'contain' : 'cover') : 'cover'"
+          @click="onPath(componentData.titleUrl)"
         />
-        <div :style="titleCss" class="title">{{ item.title || '' }}</div>
-        <div :style="subtitleCss" class="mt-[2px] mb-[12px] subtitle ellipsis">{{ item.subtitle || '' }}</div>
+        <div @click="onPath(componentData.titleUrl)" v-else class="head-title hover-color" :style="{ color: componentData.titleColor }">
+          {{ componentData.title }}
+        </div>
+        <div
+          @click="onPath(componentData.subtitleUrl)"
+          class="head-subtitle"
+          :style="subtitleCss"
+          :class="
+            componentData.styleType == 1
+              ? 'head-subtitle1'
+              : componentData.styleType == 2
+                ? 'head-subtitle2'
+                : componentData.styleType == 3
+                  ? 'head-subtitle3'
+                  : componentData.styleType == 4
+                    ? 'head-subtitle4'
+                    : ''
+          "
+        >
+          <span>{{ componentData.subtitle }}</span>
+          <img v-if="componentData.styleType == 3" class="head-image" src="@/assets/images/pcdiy/activity3-1.png" alt="" />
+        </div>
+      </div>
+      <div
+        class="trade-bos"
+        :class="
+          componentData.navType == 1 ? 'trade-bos1' : componentData.navType == 2 ? 'trade-bos2' : componentData.navType == 3 ? 'trade-bos2' : ''
+        "
+      >
+        <div
+          v-for="(item, index) in componentData.navlList"
+          :key="index"
+          class="trade-list flex-row-between hover-color"
+          :style="[radiusCss, backgroundCss(item)]"
+          @click="onPath(item.url)"
+        >
+          <div class="trade-box flex-column-between">
+            <div class="trade-title ellipsis zi-hover" :style="{ fontWeight: componentData.navWeight }">{{ item.title || '' }}</div>
+            <div class="trade-info">
+              {{ item.subtitle || '' }}
+            </div>
+            <div class="flex" v-if="componentData.navType == 3">
+              <div class="trade-look3 flex-row-start" :style="btnCss(item)">
+                <div :style="componentData.navBtnType == 2 ? 'font-style: italic' : ''">{{ item.btnText }}</div>
+                <div class="bnt-box flex-row-center">
+                  <el-icon :color="item.btncolor1"><ArrowRight /></el-icon>
+                </div>
+              </div>
+            </div>
+            <div class="flex" v-else>
+              <div class="trade-look flex-row-start" :style="btnCss(item)">
+                <img class="trade-image" src="@/assets/images/pcdiy/activity3-1.png" alt="" />
+                <div :style="componentData.navBtnType == 2 ? 'font-style: italic' : ''">{{ item.btnText }}</div>
+                <div class="bnt-box flex-row-center">
+                  <el-icon :color="item.btncolor1"><ArrowRight /></el-icon>
+                </div>
+              </div>
+            </div>
+          </div>
+          <el-image
+            class="trade-img"
+            :src="item.imageUrl ? item.imageUrl : figure"
+            :fit="item.imageUrl ? (item.imgType == 1 ? 'fill' : item.imgType == 2 ? 'contain' : 'cover') : 'cover'"
+          />
+        </div>
       </div>
     </div>
   </div>
 </template>
 
 <script lang="ts" setup>
-import usePcdiyStore from '@/store/modules/pcdiy';
+import { onPath } from '@/utils/siteConfig';
 import figure from '@/assets/images/figure.png';
-const diyStore = usePcdiyStore();
-const props = defineProps<{
-    index: number; // 确保声明 index 为可选属性
-    row?: any;
-}>();
-const componentData = props.row ? props.row : diyStore.componentList[props.index];
-
-const dataList = computed(() => {
-  const chunkSize = componentData.number * componentData.count;
-  const result = [];
-  for (let i = 0; i < componentData.navlList.length; i += chunkSize) {
-    const chunk = componentData.navlList.slice(i, i + chunkSize);
-    result.push(chunk);
-  }
-  return result;
-});
+interface Props {
+  row?: any;
+}
+const props = defineProps<Props>();
+const componentData = props.row || {};
 
 const warpCss = computed(() => {
   let style = '';
@@ -75,6 +110,15 @@ const warpCss = computed(() => {
     style += 'padding-left:' + componentData.padding.both + 'px' + ';';
     if (componentData.styleType == 1) style += 'flex-wrap:wrap' + ';';
   }
+  //间距
+  if (componentData.margin) {
+    if (componentData.margin.top > 0) {
+      style += 'margin-top:' + componentData.margin.top + 'px' + ';';
+    }
+    if (componentData.margin.bottom > 0) {
+      style += 'margin-bottom:' + componentData.margin.bottom + 'px' + ';';
+    }
+  }
   return style;
 });
 
@@ -94,79 +138,228 @@ const boxCss = computed(() => {
   return style;
 });
 
-// 标题样式
-const titleCss = computed(() => {
+// 标题样式
+const subtitleCss = computed(() => {
   let style = '';
-  if (componentData.titleColor) style += 'color:' + componentData.titleColor + ';';
-  if (componentData.titleSize) style += 'font-size:' + componentData.titleSize + 'px;';
-  if (componentData.titleWeight) style += 'font-weight:' + componentData.titleWeight + ';';
+  if (componentData.subtitleColor) style += 'color:' + componentData.subtitleColor + ';';
+  //背景颜色
+  if (componentData.subtitleColor1 && componentData.styleType != 4) {
+    if (componentData.subtitleColor1 && componentData.subtitleColor2)
+      style += `background:linear-gradient(to right,${componentData.subtitleColor1},${componentData.subtitleColor2});`;
+    else if (componentData.subtitleColor1) style += `background: ${componentData.subtitleColor1};`;
+    else if (componentData.subtitleColor2) style += `background: ${componentData.subtitleColor2};`;
+  }
   return style;
 });
 
-// 副标题样式
-const subtitleCss = computed(() => {
+//边框圆角
+const radiusCss = computed(() => {
   let style = '';
-  if (componentData.subtitleColor) style += 'color:' + componentData.subtitleColor + ';';
-  if (componentData.subtitleSize) style += 'font-size:' + componentData.subtitleSize + 'px;';
+  //圆角
+  if (componentData.navtopRounded) style += 'border-top-left-radius:' + componentData.navtopRounded + 'px;';
+  if (componentData.navtopRounded) style += 'border-top-right-radius:' + componentData.navtopRounded + 'px;';
+  if (componentData.navBtnbottomRounded) style += 'border-bottom-left-radius:' + componentData.navBtnbottomRounded + 'px;';
+  if (componentData.navBtnbottomRounded) style += 'border-bottom-right-radius:' + componentData.navBtnbottomRounded + 'px;';
   return style;
 });
+
+//背景颜色
+const backgroundCss = (row: any) => {
+  let style = '';
+  //背景颜色
+  if (row.color1) {
+    if (row.color1 && row.color2) style += `background:linear-gradient(to bottom,${row.color1},${row.color2});`;
+    else if (row.color1) style += `background: ${row.color1};`;
+    else if (row.color2) style += `background: ${row.color2};`;
+  }
+  return style;
+};
+
+// 按钮颜色
+const btnCss = (row: any) => {
+  let style = '';
+  //背景颜色
+  if (row.btncolor1) {
+    if (row.btncolor1 && row.btncolor2) style += `background:linear-gradient(to right,${row.btncolor1},${row.btncolor2});`;
+    else if (row.btncolor1) style += `background: ${row.btncolor1};`;
+    else if (row.btncolor2) style += `background: ${row.btncolor2};`;
+  }
+  return style;
+};
 </script>
 
 <style lang="scss" scoped>
 .pcPages {
   width: 1200px;
   margin: 0 auto;
-  .data-bos {
-    display: flex;
-    gap: 10px;
+  .head-bos {
     width: 100%;
-    overflow-x: auto;
-    .data-list {
-      min-height: 270px;
-      width: 0;
-
-      .title {
-        text-align: center;
-        padding: 0 15px;
+    height: 50px;
+    background-color: #ffffff;
+    padding: 0 20px;
+    .head-img {
+      height: 30px;
+      width: 150px;
+      margin-right: 10px;
+      cursor: pointer;
+    }
+    .head-title {
+      font-weight: 600;
+      font-size: 16px;
+      color: #101828;
+      margin-right: 10px;
+      cursor: pointer;
+    }
+    .head-subtitle {
+      font-size: 13px;
+      text-align: center;
+      padding: 0 15px;
+      cursor: pointer;
+      &.head-subtitle1 {
+        border-radius: 0 28px 28px 28px;
+        height: 28px;
+        line-height: 28px;
       }
-
-      .subtitle {
-        text-align: center;
-        padding: 0 15px;
+      &.head-subtitle2 {
+        border-radius: 5px;
+        height: 28px;
+        line-height: 28px;
       }
-
-      .img {
-        height: 200px;
-        width: 100%;
+      &.head-subtitle3 {
+        display: inline-block;
+        clip-path: polygon(0 0, 100% 0, 100% 100%, 5px 100%);
+        padding: 0 0 0 15px;
+        height: 28px;
+        display: flex;
+        align-items: center;
+      }
+      &.head-subtitle4 {
+        padding-left: 10px;
+        position: relative;
+        &::after {
+          content: '';
+          height: 14px;
+          width: 1px;
+          background-color: #666666;
+          position: absolute;
+          left: 0;
+          top: 2px;
+        }
+      }
+      .head-image {
+        height: 28px;
+        transform: rotate(180deg);
       }
     }
   }
-
-  .carousel-bos {
-    .carousel-list {
-      width: 100%;
-      height: 100%;
-      display: flex;
-      gap: 10px;
-      flex-wrap: wrap;
-      .data-list {
-        height: 270px;
+  .trade-bos {
+    width: 100%;
+    display: flex;
+    gap: 0 10px;
+    margin-top: 10px;
+    &.trade-bos1 {
+      .trade-list {
+        height: 146px;
+        .trade-box {
+          .trade-title {
+            font-size: 16px;
+          }
+          .trade-info {
+            font-size: 12px;
+            height: 32px;
+            display: -webkit-box;
+            -webkit-line-clamp: 2;
+            line-clamp: 2;
+            /* 添加标准属性 */
+            -webkit-box-orient: vertical;
+            overflow: hidden;
+            text-overflow: ellipsis;
+          }
+        }
+        .trade-img {
+          width: 80px;
+          height: 80px;
+        }
+      }
+    }
+    &.trade-bos2 {
+      .trade-list {
+        height: 160px;
+        .trade-box {
+          .trade-title {
+            font-size: 24px;
+          }
+          .trade-info {
+            font-size: 20px;
+            height: 32px;
+            overflow: hidden;
+            white-space: nowrap;
+            text-overflow: ellipsis;
+          }
+          .trade-look {
+            height: 35px;
+            .trade-image {
+              height: 35px;
+            }
+          }
+        }
+        .trade-img {
+          width: 100px;
+          height: 100px;
+        }
+      }
+    }
+    .trade-list {
+      flex: 1;
+      background: #ffffff;
+      border-radius: 4px;
+      padding: 22px;
+      cursor: pointer;
+      .trade-box {
+        flex: 1;
         width: 0;
-
-        .title {
-          text-align: center;
-          padding: 0 15px;
+        height: 100%;
+        .trade-title {
+          color: #000000;
         }
-
-        .subtitle {
-          text-align: center;
-          padding: 0 15px;
+        .trade-info {
+          color: #364153;
         }
-
-        .img {
-          height: 200px;
-          width: 100%;
+        .trade-look {
+          height: 28px;
+          font-size: 12px;
+          padding: 0 10px 0 0px;
+          color: #ffffff;
+          border-radius: 0 50px 50px 0px;
+          .bnt-box {
+            height: 16px;
+            width: 16px;
+            background-color: #ffffff;
+            border-radius: 16px;
+            margin-left: 10px;
+          }
+          .trade-image {
+            height: 28px;
+          }
         }
+        .trade-look3 {
+          height: 35px;
+          font-size: 14px;
+          padding: 0 15px;
+          color: #ffffff;
+          border-radius: 50px;
+          .bnt-box {
+            height: 20px;
+            width: 20px;
+            background-color: #ffffff;
+            border-radius: 20px;
+            margin-left: 10px;
+          }
+        }
+      }
+      .trade-img {
+        border-radius: 5px;
+        margin-left: 10px;
       }
     }
   }

+ 15 - 2
src/views/home/pccomponents/pages/advert.vue

@@ -4,7 +4,13 @@
       <el-carousel :height="270 * componentData.count + (componentData.count == 2 ? 10 : 0) + 'px'" :autoplay="false" arrow="always">
         <el-carousel-item v-for="(item1, index1) in dataList" :key="index1" class="w100% h100%">
           <div class="carousel-list">
-            <div v-for="(item, index) in item1" :key="index" class="data-list hover-color flex-column-between" :style="boxCss">
+            <div
+              v-for="(item, index) in item1"
+              :key="index"
+              class="data-list hover-color flex-column-between"
+              :style="boxCss"
+              @click="onPath(item.url)"
+            >
               <el-image
                 class="img"
                 :src="item.imageUrl ? item.imageUrl : figure"
@@ -19,7 +25,13 @@
       </el-carousel>
     </div>
     <div v-else class="data-bos">
-      <div v-for="(item, index) in componentData.navlList" :key="index" class="data-list hover-color flex-column-between" :style="boxCss">
+      <div
+        v-for="(item, index) in componentData.navlList"
+        :key="index"
+        class="data-list hover-color flex-column-between"
+        :style="boxCss"
+        @click="onPath(item.url)"
+      >
         <el-image
           class="img"
           :src="item.imageUrl ? item.imageUrl : figure"
@@ -34,6 +46,7 @@
 </template>
 
 <script lang="ts" setup>
+import { onPath } from '@/utils/siteConfig';
 import figure from '@/assets/images/figure.png';
 interface Props {
   row?: any;

+ 2 - 0
src/views/home/pccomponents/pages/article.vue

@@ -6,6 +6,7 @@
           class="article-list hover-color"
           :style="dataCss"
           v-if="componentData.dataType == 2 && componentData.dataIds.length > 0 ? true : index < componentData.dataNumber"
+          @click="onPath('/plan_info/project?id=' + item.id)"
         >
           <img :src="item.caseImage ? item.caseImage : figure" alt="" />
           <div class="caseTitle zi-hover">{{ item.caseTitle }}</div>
@@ -17,6 +18,7 @@
 </template>
 
 <script lang="ts" setup>
+import { onPath } from '@/utils/siteConfig';
 import { getServiceCaseList } from '@/api/home/diy';
 import figure from '@/assets/images/figure.png';
 interface Props {

+ 80 - 0
src/views/home/pccomponents/pages/blank.vue

@@ -0,0 +1,80 @@
+<template>
+  <div class="pcPages" :style="warpCss">
+    <div :style="boxCss"></div>
+  </div>
+</template>
+
+<script setup lang="ts">
+interface Props {
+  row?: any;
+}
+const props = defineProps<Props>();
+const componentData = props.row || {};
+const warpCss = computed(() => {
+  let style = '';
+  style += 'position:relative;';
+  //背景颜色
+  if (componentData.pageStartBgColor) {
+    if (componentData.pageStartBgColor && componentData.pageEndBgColor)
+      style += `background:linear-gradient(${componentData.pageGradientAngle},${componentData.pageStartBgColor},${componentData.pageEndBgColor});`;
+    else if (componentData.pageStartBgColor) style += `background: ${componentData.pageStartBgColor};`;
+    else if (componentData.pageEndBgColor) style += `background: ${componentData.pageEndBgColor};`;
+  }
+  //背景图片
+  if (componentData.componentBgUrl) {
+    style += `background-image:url('${componentData.componentBgUrl}');`;
+    style += 'background-size: cover;background-repeat: no-repeat;';
+  }
+  //边距
+  if (componentData.padding) {
+    if (componentData.padding.top > 0) {
+      style += 'padding-top:' + componentData.padding.top + 'px' + ';';
+    }
+    if (componentData.padding.bottom > 0) {
+      style += 'padding-bottom:' + componentData.padding.bottom + 'px' + ';';
+    }
+    style += 'padding-right:' + componentData.padding.both + 'px' + ';';
+    style += 'padding-left:' + componentData.padding.both + 'px' + ';';
+  }
+  //圆角
+  if (componentData.topRounded) style += 'border-top-left-radius:' + componentData.topRounded + 'px;';
+  if (componentData.topRounded) style += 'border-top-right-radius:' + componentData.topRounded + 'px;';
+  if (componentData.bottomRounded) style += 'border-bottom-left-radius:' + componentData.bottomRounded + 'px;';
+  if (componentData.bottomRounded) style += 'border-bottom-right-radius:' + componentData.bottomRounded + 'px;';
+
+  //间距
+  if (componentData.margin) {
+    if (componentData.margin.top > 0) {
+      style += 'margin-top:' + componentData.margin.top + 'px' + ';';
+    }
+    if (componentData.margin.bottom > 0) {
+      style += 'margin-bottom:' + componentData.margin.bottom + 'px' + ';';
+    }
+  }
+  return style;
+});
+
+//组件样式
+const boxCss = computed(() => {
+  let style = '';
+  if (componentData.componentStartBgColor && componentData.componentEndBgColor)
+    style += `background:linear-gradient(${componentData.componentGradientAngle},${componentData.componentStartBgColor},${componentData.componentEndBgColor});`;
+  else if (componentData.componentStartBgColor) style += 'background-color:' + componentData.componentStartBgColor + ';';
+  else if (componentData.componentEndBgColor) style += 'background-color:' + componentData.componentEndBgColor + ';';
+  if (componentData.number) style += 'flex:' + `0 0 calc((100% - ${(componentData.number - 1) * 10}px) / ${componentData.number})` + ';';
+  if (componentData.boxHeight) style += 'height:' + componentData.boxHeight + 'px;';
+  return style;
+});
+</script>
+<style lang="scss" scoped>
+.pcPages {
+  width: 1200px;
+  margin: 0 auto;
+  .pcPages-html {
+    :deep(img) {
+      max-width: 100%;
+      display: inline-block;
+    }
+  }
+}
+</style>

+ 90 - 0
src/views/home/pccomponents/pages/border.vue

@@ -0,0 +1,90 @@
+<template>
+  <div class="pcPages" :style="warpCss">
+    <div :style="boxCss">
+      <div :style="borderCss" class="w100%"></div>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+interface Props {
+  row?: any;
+}
+const props = defineProps<Props>();
+const componentData = props.row || {};
+const warpCss = computed(() => {
+  let style = '';
+  style += 'position:relative;';
+  //背景颜色
+  if (componentData.pageStartBgColor) {
+    if (componentData.pageStartBgColor && componentData.pageEndBgColor)
+      style += `background:linear-gradient(${componentData.pageGradientAngle},${componentData.pageStartBgColor},${componentData.pageEndBgColor});`;
+    else if (componentData.pageStartBgColor) style += `background: ${componentData.pageStartBgColor};`;
+    else if (componentData.pageEndBgColor) style += `background: ${componentData.pageEndBgColor};`;
+  }
+  //背景图片
+  if (componentData.componentBgUrl) {
+    style += `background-image:url('${componentData.componentBgUrl}');`;
+    style += 'background-size: cover;background-repeat: no-repeat;';
+  }
+  //边距
+  if (componentData.padding) {
+    if (componentData.padding.top > 0) {
+      style += 'padding-top:' + componentData.padding.top + 'px' + ';';
+    }
+    if (componentData.padding.bottom > 0) {
+      style += 'padding-bottom:' + componentData.padding.bottom + 'px' + ';';
+    }
+    style += 'padding-right:' + componentData.padding.both + 'px' + ';';
+    style += 'padding-left:' + componentData.padding.both + 'px' + ';';
+  }
+  //圆角
+  if (componentData.topRounded) style += 'border-top-left-radius:' + componentData.topRounded + 'px;';
+  if (componentData.topRounded) style += 'border-top-right-radius:' + componentData.topRounded + 'px;';
+  if (componentData.bottomRounded) style += 'border-bottom-left-radius:' + componentData.bottomRounded + 'px;';
+  if (componentData.bottomRounded) style += 'border-bottom-right-radius:' + componentData.bottomRounded + 'px;';
+
+  //间距
+  if (componentData.margin) {
+    if (componentData.margin.top > 0) {
+      style += 'margin-top:' + componentData.margin.top + 'px' + ';';
+    }
+    if (componentData.margin.bottom > 0) {
+      style += 'margin-bottom:' + componentData.margin.bottom + 'px' + ';';
+    }
+  }
+  return style;
+});
+
+//组件样式
+const boxCss = computed(() => {
+  let style = '';
+  if (componentData.componentStartBgColor && componentData.componentEndBgColor)
+    style += `background:linear-gradient(${componentData.componentGradientAngle},${componentData.componentStartBgColor},${componentData.componentEndBgColor});`;
+  else if (componentData.componentStartBgColor) style += 'background-color:' + componentData.componentStartBgColor + ';';
+  else if (componentData.componentEndBgColor) style += 'background-color:' + componentData.componentEndBgColor + ';';
+  if (componentData.number) style += 'flex:' + `0 0 calc((100% - ${(componentData.number - 1) * 10}px) / ${componentData.number})` + ';';
+  if (componentData.boxHeight) style += 'height:' + componentData.boxHeight + 'px;';
+  return style;
+});
+
+//组件样式
+const borderCss = computed(() => {
+  let style = '';
+  if (componentData.boxHeight) style += 'height:' + componentData.boxHeight + 'px;';
+  if (componentData.boxColor) style += 'background-color:' + componentData.boxColor;
+  return style;
+});
+</script>
+<style lang="scss" scoped>
+.pcPages {
+  width: 1200px;
+  margin: 0 auto;
+  .pcPages-html {
+    :deep(img) {
+      max-width: 100%;
+      display: inline-block;
+    }
+  }
+}
+</style>

+ 4 - 0
src/views/home/pccomponents/pages/brand.vue

@@ -6,6 +6,7 @@
         :src="componentData.imageUrl ? componentData.imageUrl : figure"
         :fit="componentData.imageUrl ? (componentData.imgType == 1 ? 'fill' : componentData.imgType == 2 ? 'contain' : 'cover') : 'cover'"
         :style="componentData.boxRadius ? { borderRadius: componentData.boxRadius + 'px' } : {}"
+        @click="onPath(componentData.url)"
       />
       <div class="bigBrand-bos">
         <template v-for="(item, index) in componentData.brandList" :key="index">
@@ -13,6 +14,7 @@
             class="bigBrand-list hover-color"
             v-if="Number(index) < 10"
             :style="componentData.boxRadius ? { borderRadius: componentData.boxRadius + 'px' } : {}"
+            @click="onPath(item.url)"
           >
             <el-image
               class="img"
@@ -34,6 +36,7 @@
 <script lang="ts" setup>
 import figure from '@/assets/images/figure.png';
 import brand1 from '@/assets/images/pcdiy/brand1.png';
+import { onPath } from '@/utils/siteConfig';
 interface Props {
   row?: any;
 }
@@ -127,6 +130,7 @@ const subtitleCss = computed(() => {
     .bigBrand-one {
       width: 230px;
       height: 340px;
+      cursor: pointer;
     }
 
     .bigBrand-bos {

+ 2 - 1
src/views/home/pccomponents/pages/carousel.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="pcPages" :style="warpCss" :class="['position' + componentData.position, 'styleType' + componentData.styleType]">
     <el-carousel arrow="always" :interval="componentData.interval" :height="componentData.imageHeight + 'px'" class="carousel-bos" :style="boxCss">
-      <el-carousel-item v-for="(item, index) in componentData.imagelList" :key="index" class="carousel-item">
+      <el-carousel-item v-for="(item, index) in componentData.imagelList" :key="index" class="carousel-item" @click="onPath(item.url)">
         <el-image
           class="img"
           :src="item.imageUrl ? item.imageUrl : figure"
@@ -16,6 +16,7 @@
 interface Props {
   row?: any;
 }
+import { onPath } from '@/utils/siteConfig';
 const props = defineProps<Props>();
 const componentData = props.row || {};
 document.documentElement.style.setProperty('--carousel-color2', componentData.carouselStyleColor ? componentData.carouselStyleColor : '#ffffff');

+ 64 - 49
src/views/home/pccomponents/pages/discover.vue

@@ -3,12 +3,14 @@
     <div class="discover-bos" :style="boxCss">
       <!-- 头部 -->
       <div class="home-title flex-row-between" :style="componentData.boxRadius ? { borderRadius: componentData.boxRadius + 'px' } : {}">
-        <div>
-          <span :style="titleCss" class="title1 mr-[10px]">{{ componentData.title }}</span>
+        <div @click="onPath(componentData.titleUrl)">
+          <span :style="titleCss" class="title1 mr-[10px] hover-color">{{ componentData.title }}</span>
           <span :style="subtitleCss">{{ componentData.subtitle }}</span>
         </div>
         <div class="title-more flex-row-start">
-          <div class="ml-[10px]" v-for="(item, index) in componentData.labelList" :key="index">{{ item.title }}</div>
+          <div @click="onPath(item.url)" class="ml-[10px] hover-color" v-for="(item, index) in componentData.labelList" :key="index">
+            {{ item.title }}
+          </div>
         </div>
       </div>
       <!-- 中间区域 -->
@@ -16,12 +18,12 @@
         <el-image
           class="discover-image"
           :src="componentData.imageUrl ? componentData.imageUrl : figure"
-          :fit="componentData.imgType == 1 ? 'fill' : componentData.imgType == 2 ? 'contain' : 'cover'"
+          :fit="componentData.imageUrl ? (componentData.imgType == 1 ? 'fill' : componentData.imgType == 2 ? 'contain' : 'cover') : 'cover'"
           :style="componentData.boxRadius ? { borderRadius: componentData.boxRadius + 'px' } : {}"
         />
         <div class="plan-bos" :style="componentData.boxRadius ? { borderRadius: componentData.boxRadius + 'px' } : {}">
           <div class="plan-head">方案推荐</div>
-          <div v-for="(item, index) in componentData.planList" :key="index" class="plan-list">
+          <div v-for="(item, index) in componentData.planList" :key="index" class="plan-list hover-color" @click="onPath(item.url)">
             <el-image
               class="plan-image"
               :src="item.imageUrl ? item.imageUrl : figure"
@@ -29,7 +31,7 @@
               :style="componentData.imageRadius ? { borderRadius: componentData.imageRadius + 'px' } : {}"
             />
             <div class="plan-box flex-column-between">
-              <div class="plan-title ellipsis">{{ item.title }}</div>
+              <div class="plan-title ellipsis zi-hover">{{ item.title }}</div>
               <div class="plan-subtitle">{{ item.subtitle }}</div>
             </div>
           </div>
@@ -38,9 +40,13 @@
           <div class="detect-head">发现</div>
           <div class="detect-box">
             <div class="detect-two">
-              <div class="detect-list" :style="componentData.boxRadius ? { borderRadius: componentData.boxRadius + 'px' } : {}">
+              <div
+                @click="onPath(componentData.detectList[0].url)"
+                class="detect-list hover-color"
+                :style="componentData.boxRadius ? { borderRadius: componentData.boxRadius + 'px' } : {}"
+              >
                 <div class="detect-item">
-                  <div class="detect-title ellipsis">{{ componentData.detectList[0].title }}</div>
+                  <div class="detect-title ellipsis zi-hover">{{ componentData.detectList[0].title }}</div>
                   <div class="detect-subtitle mt-[6px] h-[32px]">{{ componentData.detectList[0].subtitle }}</div>
                   <div class="detect-btn" :style="{ backgroundColor: componentData.boxColor }">立即进入</div>
                 </div>
@@ -51,9 +57,13 @@
                   :style="componentData.imageRadius ? { borderRadius: componentData.imageRadius + 'px' } : {}"
                 />
               </div>
-              <div class="detect-list" :style="componentData.boxRadius ? { borderRadius: componentData.boxRadius + 'px' } : {}">
+              <div
+                @click="onPath(componentData.detectList[1].url)"
+                class="detect-list hover-color"
+                :style="componentData.boxRadius ? { borderRadius: componentData.boxRadius + 'px' } : {}"
+              >
                 <div class="detect-item">
-                  <div class="detect-title ellipsis">{{ componentData.detectList[1].title }}</div>
+                  <div class="detect-title ellipsis zi-hover">{{ componentData.detectList[1].title }}</div>
                   <div class="detect-subtitle mt-[6px] h-[32px]">{{ componentData.detectList[1].subtitle }}</div>
                   <div class="detect-btn" :style="{ backgroundColor: componentData.boxColor }">立即进入</div>
                 </div>
@@ -65,9 +75,13 @@
                 />
               </div>
             </div>
-            <div class="detect-one flex-column-between" :style="componentData.boxRadius ? { borderRadius: componentData.boxRadius + 'px' } : {}">
+            <div
+              class="detect-one flex-column-between hover-color"
+              :style="componentData.boxRadius ? { borderRadius: componentData.boxRadius + 'px' } : {}"
+              @click="onPath(componentData.detectList[2].url)"
+            >
               <div>
-                <div class="detect-title ellipsis">{{ componentData.detectList[2].title }}</div>
+                <div class="detect-title ellipsis zi-hover">{{ componentData.detectList[2].title }}</div>
                 <div class="detect-subtitle mt-[6px]">{{ componentData.detectList[2].subtitle }}</div>
               </div>
               <el-image
@@ -85,44 +99,44 @@
         <div class="discover-tab" :style="componentData.boxRadius ? { borderRadius: componentData.boxRadius + 'px' } : {}">
           <div class="tab-head" :style="{ color: componentData.boxColor }">采购导航</div>
           <div class="tab-bos">
-            <div v-for="(item, index) in componentData.tabList" :key="index" class="tab-list flex-row-center">
+            <div @click="onPath(item.url)" v-for="(item, index) in componentData.tabList" :key="index" class="tab-list flex-row-center hover-color">
               {{ item.title }}
             </div>
           </div>
         </div>
-        <div
-          class="goods-bos flex-column-between"
-          v-for="(item, index) in dataList"
-          :key="index"
-          :style="componentData.boxRadius ? { borderRadius: componentData.boxRadius + 'px' } : {}"
-        >
-          <img
-            class="goods-img"
-            :src="item.productImage ? item.productImage : figure"
-            alt=""
-            :style="componentData.imageRadius ? { borderRadius: componentData.imageRadius + 'px' } : {}"
-          />
-          <div>
-            <div class="goods-name">{{ item.itemName || '' }}</div>
-            <div class="goods-price" :style="{ color: componentData.boxColor }">¥{{ item.memberPrice }}</div>
+        <template v-for="(item, index) in dataList" :key="index">
+          <div
+            v-if="Number(index) < 4"
+            class="goods-bos flex-column-between hover-color"
+            :style="componentData.boxRadius ? { borderRadius: componentData.boxRadius + 'px' } : {}"
+            @click="onPath('/item?id=' + item.id)"
+          >
+            <img
+              class="goods-img"
+              :src="item.productImage ? item.productImage : figure"
+              alt=""
+              :style="componentData.imageRadius ? { borderRadius: componentData.imageRadius + 'px' } : {}"
+            />
+            <div>
+              <div class="goods-name zi-hover">{{ item.itemName || '商品名称' }}</div>
+              <div class="goods-price" :style="{ color: componentData.boxColor }">¥{{ item.memberPrice || '0.00' }}</div>
+            </div>
           </div>
-        </div>
+        </template>
       </div>
     </div>
   </div>
 </template>
 
 <script setup lang="ts">
+import { onPath } from '@/utils/siteConfig';
 import figure from '@/assets/images/figure.png';
-import usePcdiyStore from '@/store/modules/pcdiy';
-import { listBase } from '@/api/pmsProduct/base';
-const diyStore = usePcdiyStore();
-
-const props = defineProps<{
-    index: number; // 确保声明 index 为可选属性
+import { getDiyProductPage } from '@/api/home/diy';
+interface Props {
   row?: any;
-}>();
-const componentData = props.row ? props.row : diyStore.componentList[props.index];
+}
+const props = defineProps<Props>();
+const componentData = props.row || {};
 const dataList = ref<any>([{}, {}, {}, {}]);
 
 onMounted(() => {
@@ -132,7 +146,7 @@ onMounted(() => {
 const getDataList = () => {
   dataList.value = [{}, {}, {}, {}];
   if (componentData.goodsIds.length > 0) {
-    listBase({ pageNum: 1, pageSize: 10, ids: componentData.goodsIds.join(',') }).then((res) => {
+    getDiyProductPage({ pageNum: 1, pageSize: 10, ids: componentData.goodsIds.join(',') }).then((res) => {
       if (res.code == 200) {
         dataList.value = res.rows;
       }
@@ -140,14 +154,6 @@ const getDataList = () => {
   }
 };
 
-watch(
-  () => componentData.goodsIds,
-  () => {
-    getDataList();
-  },
-  { deep: true } // 5. 数组变化需要 deep 监听
-);
-
 const warpCss = computed(() => {
   let style = '';
   style += 'position:relative;';
@@ -179,7 +185,15 @@ const warpCss = computed(() => {
   if (componentData.topRounded) style += 'border-top-right-radius:' + componentData.topRounded + 'px;';
   if (componentData.bottomRounded) style += 'border-bottom-left-radius:' + componentData.bottomRounded + 'px;';
   if (componentData.bottomRounded) style += 'border-bottom-right-radius:' + componentData.bottomRounded + 'px;';
-
+  //间距
+  if (componentData.margin) {
+    if (componentData.margin.top > 0) {
+      style += 'margin-top:' + componentData.margin.top + 'px' + ';';
+    }
+    if (componentData.margin.bottom > 0) {
+      style += 'margin-bottom:' + componentData.margin.bottom + 'px' + ';';
+    }
+  }
   return style;
 });
 
@@ -232,13 +246,14 @@ const subtitleCss = computed(() => {
   .discover-box {
     height: 340px;
     width: 100%;
-    margin-top: 15px;
+    margin-top: 10px;
     display: flex;
     gap: 10px;
 
     .discover-image {
       width: 230px;
       height: 340px;
+      cursor: pointer;
     }
 
     // 方案
@@ -390,7 +405,7 @@ const subtitleCss = computed(() => {
   .discover-foot {
     display: flex;
     gap: 10px;
-    margin-top: 15px;
+    margin-top: 10px;
     .discover-tab {
       width: 230px;
       height: 310px;

+ 81 - 0
src/views/home/pccomponents/pages/editordiy.vue

@@ -0,0 +1,81 @@
+<template>
+  <div class="pcPages" :style="warpCss">
+    <div :style="boxCss">
+      <div class="pcPages-html" v-html="componentData.detail"></div>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+interface Props {
+  row?: any;
+}
+const props = defineProps<Props>();
+const componentData = props.row || {};
+const warpCss = computed(() => {
+  let style = '';
+  style += 'position:relative;';
+  //背景颜色
+  if (componentData.pageStartBgColor) {
+    if (componentData.pageStartBgColor && componentData.pageEndBgColor)
+      style += `background:linear-gradient(${componentData.pageGradientAngle},${componentData.pageStartBgColor},${componentData.pageEndBgColor});`;
+    else if (componentData.pageStartBgColor) style += `background: ${componentData.pageStartBgColor};`;
+    else if (componentData.pageEndBgColor) style += `background: ${componentData.pageEndBgColor};`;
+  }
+  //背景图片
+  if (componentData.componentBgUrl) {
+    style += `background-image:url('${componentData.componentBgUrl}');`;
+    style += 'background-size: cover;background-repeat: no-repeat;';
+  }
+  //边距
+  if (componentData.padding) {
+    if (componentData.padding.top > 0) {
+      style += 'padding-top:' + componentData.padding.top + 'px' + ';';
+    }
+    if (componentData.padding.bottom > 0) {
+      style += 'padding-bottom:' + componentData.padding.bottom + 'px' + ';';
+    }
+    style += 'padding-right:' + componentData.padding.both + 'px' + ';';
+    style += 'padding-left:' + componentData.padding.both + 'px' + ';';
+  }
+  //圆角
+  if (componentData.topRounded) style += 'border-top-left-radius:' + componentData.topRounded + 'px;';
+  if (componentData.topRounded) style += 'border-top-right-radius:' + componentData.topRounded + 'px;';
+  if (componentData.bottomRounded) style += 'border-bottom-left-radius:' + componentData.bottomRounded + 'px;';
+  if (componentData.bottomRounded) style += 'border-bottom-right-radius:' + componentData.bottomRounded + 'px;';
+
+  //间距
+  if (componentData.margin) {
+    if (componentData.margin.top > 0) {
+      style += 'margin-top:' + componentData.margin.top + 'px' + ';';
+    }
+    if (componentData.margin.bottom > 0) {
+      style += 'margin-bottom:' + componentData.margin.bottom + 'px' + ';';
+    }
+  }
+  return style;
+});
+
+//组件样式
+const boxCss = computed(() => {
+  let style = '';
+  if (componentData.componentStartBgColor && componentData.componentEndBgColor)
+    style += `background:linear-gradient(${componentData.componentGradientAngle},${componentData.componentStartBgColor},${componentData.componentEndBgColor});`;
+  else if (componentData.componentStartBgColor) style += 'background-color:' + componentData.componentStartBgColor + ';';
+  else if (componentData.componentEndBgColor) style += 'background-color:' + componentData.componentEndBgColor + ';';
+  if (componentData.number) style += 'flex:' + `0 0 calc((100% - ${(componentData.number - 1) * 10}px) / ${componentData.number})` + ';';
+  return style;
+});
+</script>
+<style lang="scss" scoped>
+.pcPages {
+  width: 1200px;
+  margin: 0 auto;
+  .pcPages-html {
+    :deep(img) {
+      max-width: 100%;
+      display: inline-block;
+    }
+  }
+}
+</style>

+ 31 - 23
src/views/home/pccomponents/pages/floor.vue

@@ -2,26 +2,27 @@
   <div class="pcPages" :style="warpCss">
     <div class="floor-bos" :style="boxCss">
       <el-image
+        @click="onPath(componentData.url)"
         class="floor-one"
         :src="componentData.imageUrl ? componentData.imageUrl : figure"
-        :fit="componentData.imgType == 1 ? 'fill' : componentData.imgType == 2 ? 'contain' : 'cover'"
+        :fit="componentData.imageUrl ? (componentData.imgType == 1 ? 'fill' : componentData.imgType == 2 ? 'contain' : 'cover') : 'cover'"
         :style="componentData.imageRadius ? { borderRadius: componentData.imageRadius + 'px' } : {}"
       />
       <div class="floor-box">
-        <div v-for="(item, index) in dataList" :key="index" class="goods-list flex-column-between">
+        <div v-for="(item, index) in dataList" :key="index" class="goods-list flex-column-between hover-color" @click="onPath('/item?id' + item.id)">
           <img
             class="goods-img"
             :src="item.productImage ? item.productImage : figure"
             alt=""
             :style="componentData.imageRadius ? { borderRadius: componentData.imageRadius + 'px' } : {}"
           />
-          <div v-if="componentData.goodsShow.includes(1)" class="itemName">{{ item.itemName || '' }}</div>
+          <div v-if="componentData.goodsShow.includes(1)" class="itemName zi-hover">{{ item.itemName || '商品名称' }}</div>
           <div class="flex-row-between">
             <div>
               <span v-if="componentData.goodsShow.includes(2)" class="memberPrice" :style="{ color: componentData.btnbackgroundColor }"
-                >¥{{ item.memberPrice }}</span
+                >¥{{ item.memberPrice || '0.00' }}</span
               >
-              <span v-if="componentData.goodsShow.includes(3)" class="marketPrice">¥{{ item.marketPrice }}</span>
+              <span v-if="componentData.goodsShow.includes(3)" class="marketPrice">¥{{ item.marketPrice || '0.00' }}</span>
             </div>
             <template v-if="componentData.btnShow">
               <div v-if="componentData.btnStyle == 1" :style="btnCss1" class="btn1 ellipsis">{{ componentData.btnText }}</div>
@@ -43,10 +44,16 @@
               class="brand-img"
               :src="item.imageUrl ? item.imageUrl : figure"
               :fit="item.imgType == 1 ? 'fill' : item.imgType == 2 ? 'contain' : 'cover'"
+              @click="onPath(item.url)"
             />
           </template>
         </div>
-        <div class="brand-more flex-row-center" v-if="componentData.moreShow" :style="{ color: componentData.moreColor }">
+        <div
+          @click="onPath(componentData.moreUrl)"
+          class="brand-more flex-row-center"
+          v-if="componentData.moreShow"
+          :style="{ color: componentData.moreColor }"
+        >
           <div>{{ componentData.moreTitle }}</div>
           <el-icon><ArrowRight /></el-icon>
         </div>
@@ -56,35 +63,26 @@
 </template>
 
 <script setup lang="ts">
+import { onPath } from '@/utils/siteConfig';
 import figure from '@/assets/images/figure.png';
-import usePcdiyStore from '@/store/modules/pcdiy';
-import { listBase } from '@/api/pmsProduct/base';
-const diyStore = usePcdiyStore();
-
-const props = defineProps<{
-    index: number; // 确保声明 index 为可选属性
+import { getDiyProductPage } from '@/api/home/diy';
+interface Props {
   row?: any;
-}>();
-const componentData = props.row ? props.row : diyStore.componentList[props.index];
+}
+
+const props = defineProps<Props>();
+const componentData = props.row || {};
 const dataList = ref<any>([{}, {}, {}, {}, {}, {}, {}, {}]);
 
 onMounted(() => {
   getDataList();
 });
 
-watch(
-  () => componentData.goodsIds,
-  () => {
-    getDataList();
-  },
-  { deep: true } // 5. 数组变化需要 deep 监听
-);
-
 const getDataList = () => {
   dataList.value = [{}, {}, {}, {}, {}, {}, {}, {}];
   //手动选择
   if (componentData.goodsIds.length > 0) {
-    listBase({ pageNum: 1, pageSize: 20, ids: componentData.goodsIds.join(',') }).then((res) => {
+    getDiyProductPage({ pageNum: 1, pageSize: 20, ids: componentData.goodsIds.join(',') }).then((res) => {
       if (res.code == 200) {
         dataList.value = res.rows;
       }
@@ -122,6 +120,15 @@ const warpCss = computed(() => {
   if (componentData.topRounded) style += 'border-top-right-radius:' + componentData.topRounded + 'px;';
   if (componentData.bottomRounded) style += 'border-bottom-left-radius:' + componentData.bottomRounded + 'px;';
   if (componentData.bottomRounded) style += 'border-bottom-right-radius:' + componentData.bottomRounded + 'px;';
+  //间距
+  if (componentData.margin) {
+    if (componentData.margin.top > 0) {
+      style += 'margin-top:' + componentData.margin.top + 'px' + ';';
+    }
+    if (componentData.margin.bottom > 0) {
+      style += 'margin-bottom:' + componentData.margin.bottom + 'px' + ';';
+    }
+  }
 
   return style;
 });
@@ -164,6 +171,7 @@ const btnCss2 = computed(() => {
     .floor-one {
       width: 230px;
       height: 560px;
+      cursor: pointer;
     }
     .floor-box {
       flex: 1;

+ 99 - 65
src/views/home/pccomponents/pages/goods.vue

@@ -1,23 +1,29 @@
 <template>
   <div class="pcPages" :style="warpCss">
-    <div class="goods-bos" :style="boxCss">
-      <div v-for="(item, index) in dataList" :key="index" class="goods-list flex-column-between" :style="goodsCss">
+    <div class="goods-bos" :style="boxCss" v-if="componentData.styleType == 1">
+      <div
+        v-for="(item, index) in dataList"
+        :key="index"
+        class="goods-list flex-column-between hover-color"
+        :style="goodsCss"
+        @click="onPath('/item?id=' + item.id)"
+      >
         <img
           class="goods-img"
           :src="item.productImage ? item.productImage : figure"
           alt=""
           :style="componentData.imageRadius ? { borderRadius: componentData.imageRadius + 'px' } : {}"
         />
-        <div v-if="componentData.goodsShow.includes(1)" :style="titleCss" class="itemName">{{ item.itemName || '' }}</div>
+        <div v-if="componentData.goodsShow.includes(1)" :style="titleCss" class="itemName zi-hover">{{ item.itemName || '商品名称' }}</div>
         <div class="flex-row-between">
           <div>
             <span v-if="componentData.goodsShow.includes(2)" class="memberPrice" :style="{ color: componentData.priceColor }"
-              >¥{{ item.memberPrice }}</span
+              >¥{{ item.memberPrice || '0.00' }}</span
             >
-            <span v-if="componentData.goodsShow.includes(3)" class="marketPrice">¥{{ item.marketPrice }}</span>
+            <span v-if="componentData.goodsShow.includes(3)" class="marketPrice">¥{{ item.marketPrice || '0.00' }}</span>
           </div>
           <template v-if="componentData.btnShow">
-            <div v-if="componentData.btnStyle == 1" :style="btnCss1" class="btn1">{{ componentData.btnText }}</div>
+            <div v-if="componentData.btnStyle == 1" :style="btnCss1" class="btn1">{{ componentData.btnText || '购买' }}</div>
             <div v-if="componentData.btnStyle == 2" :style="btnCss2" class="btn2 flex-row-center">
               <el-icon size="14"><Plus /></el-icon>
             </div>
@@ -28,103 +34,123 @@
         </div>
       </div>
     </div>
+    <div v-else :style="boxCss">
+      <el-carousel height="300px" arrow="always" autoplay>
+        <el-carousel-item v-for="(item1, index1) in dataList" :key="index1" class="w100% h100%">
+          <div class="goods-bos">
+            <div
+              v-for="(item, index) in item1"
+              :key="index"
+              class="goods-list flex-column-between hover-color"
+              :style="goodsCss"
+              @click="onPath('/item?id=' + item.id)"
+            >
+              <img
+                class="goods-img"
+                :src="item.productImage ? item.productImage : figure"
+                alt=""
+                :style="componentData.imageRadius ? { borderRadius: componentData.imageRadius + 'px' } : {}"
+              />
+              <div v-if="componentData.goodsShow.includes(1)" :style="titleCss" class="itemName zi-hover">{{ item.itemName || '商品名称' }}</div>
+              <div class="flex-row-between">
+                <div>
+                  <span v-if="componentData.goodsShow.includes(2)" class="memberPrice" :style="{ color: componentData.priceColor }"
+                    >¥{{ item.memberPrice || '0.00' }}</span
+                  >
+                  <span v-if="componentData.goodsShow.includes(3)" class="marketPrice">¥{{ item.marketPrice || '0.00' }}</span>
+                </div>
+                <template v-if="componentData.btnShow">
+                  <div v-if="componentData.btnStyle == 1" :style="btnCss1" class="btn1">{{ componentData.btnText || '购买' }}</div>
+                  <div v-if="componentData.btnStyle == 2" :style="btnCss2" class="btn2 flex-row-center">
+                    <el-icon size="14"><Plus /></el-icon>
+                  </div>
+                  <div v-if="componentData.btnStyle == 3" :style="btnCss2" class="btn2 flex-row-center">
+                    <icon name="iconfont icongouwuche" size="14px" />
+                  </div>
+                </template>
+              </div>
+            </div>
+          </div>
+        </el-carousel-item>
+      </el-carousel>
+    </div>
   </div>
 </template>
 
 <script lang="ts" setup>
+import { onPath } from '@/utils/siteConfig';
 import figure from '@/assets/images/figure.png';
-import usePcdiyStore from '@/store/modules/pcdiy';
-import { listBase } from '@/api/pmsProduct/base';
-const diyStore = usePcdiyStore();
+import { getDiyProductPage } from '@/api/home/diy';
 
-const props = defineProps<{
-   index: number; // 确保声明 index 为可选属性
+interface Props {
   row?: any;
-}>();
-const componentData = props.row ? props.row : diyStore.componentList[props.index];
-const dataList = ref<any>([{}, {}, {}, {}, {}]);
+}
+
+const props = defineProps<Props>();
+const componentData = props.row || {};
+const original = ref<any>([{}, {}, {}, {}, {}]);
 
 onMounted(() => {
   getDataList();
 });
 
 const getDataList = () => {
-  dataList.value = [{}, {}, {}, {}, {}];
+  original.value = [{}, {}, {}, {}, {}];
   //手动选择
   if (componentData.goodsType == 1) {
     if (componentData.goodsIds.length > 0) {
-      listBase({ pageNum: 1, pageSize: 20, ids: componentData.goodsIds.join(',') }).then((res) => {
+      getDiyProductPage({ pageNum: 1, pageSize: 20, ids: componentData.goodsIds.join(',') }).then((res) => {
         if (res.code == 200) {
-          dataList.value = res.rows;
+          original.value = res.rows;
         }
       });
     }
   } else if (componentData.goodsType == 2) {
     //分类查询
-    if (componentData.goodsClassify) {
-      listBase({
+    if (componentData.categoryIds && componentData.categoryIds.length > 0) {
+      const categoryIds = componentData.categoryIds.map((item: any) => item[2]);
+      getDiyProductPage({
         pageNum: 1,
-        pageSize: componentData.goodsNumber == 0 ? 50 : componentData.goodsNumber,
-        topCategoryId: componentData.topCategoryId,
-        mediumCategoryId: componentData.mediumCategoryId,
-        bottomCategoryId: componentData.bottomCategoryId
+        pageSize: componentData.goodsNumber == 0 ? 9999 : componentData.goodsNumber,
+        categoryIds: categoryIds.join(',')
       }).then((res) => {
         if (res.code == 200) {
-          dataList.value = res.rows;
+          if (res.rows && res.rows.length > 0) {
+            original.value = res.rows;
+          }
         }
       });
     }
   } else if (componentData.goodsType == 3) {
     //品牌查询
-    if (componentData.goodsBrand) {
-      listBase({
+    if (componentData.brandIds && componentData.brandIds.length > 0) {
+      getDiyProductPage({
         pageNum: 1,
-        pageSize: componentData.goodsNumber == 0 ? 50 : componentData.goodsNumber,
-        brandId: componentData.goodsBrand
+        pageSize: componentData.goodsNumber == 0 ? 9999 : componentData.goodsNumber,
+        brandIds: componentData.brandIds.join(',')
       }).then((res) => {
         if (res.code == 200) {
-          dataList.value = res.rows;
+          if (res.rows && res.rows.length > 0) {
+            original.value = res.rows;
+          }
         }
       });
     }
   }
 };
 
-watch(
-  () => componentData.goodsType,
-  () => {
-    getDataList();
-  }
-);
-
-watch(
-  () => componentData.goodsClassify,
-  () => {
-    getDataList();
-  }
-);
-
-watch(
-  () => componentData.goodsNumber,
-  () => {
-    getDataList();
-  }
-);
-
-watch(
-  () => componentData.goodsBrand,
-  () => {
-    getDataList();
+const dataList = computed(() => {
+  if (componentData.styleType == 1) {
+    return original.value;
+  } else {
+    const pageSize = 5;
+    const groupedUsers = [];
+    for (let i = 0; i < original.value.length; i += pageSize) {
+      groupedUsers.push(original.value.slice(i, i + pageSize));
+    }
+    return groupedUsers;
   }
-);
-
-watch(
-  () => componentData.goodsIds,
-  () => {
-    getDataList();
-  },
-  { deep: true } // 5. 数组变化需要 deep 监听
-);
+});
 
 const warpCss = computed(() => {
   let style = '';
@@ -157,7 +183,15 @@ const warpCss = computed(() => {
   if (componentData.topRounded) style += 'border-top-right-radius:' + componentData.topRounded + 'px;';
   if (componentData.bottomRounded) style += 'border-bottom-left-radius:' + componentData.bottomRounded + 'px;';
   if (componentData.bottomRounded) style += 'border-bottom-right-radius:' + componentData.bottomRounded + 'px;';
-
+  //间距
+  if (componentData.margin) {
+    if (componentData.margin.top > 0) {
+      style += 'margin-top:' + componentData.margin.top + 'px' + ';';
+    }
+    if (componentData.margin.bottom > 0) {
+      style += 'margin-bottom:' + componentData.margin.bottom + 'px' + ';';
+    }
+  }
   return style;
 });
 
@@ -221,13 +255,13 @@ const btnCss2 = computed(() => {
   .goods-bos {
     display: flex;
     gap: 10px;
-    overflow: auto;
     .goods-list {
       padding: 20px 15px;
       height: 300px;
       width: 0;
       flex: 0 0 calc((100% - 40px) / 5);
       overflow: hidden;
+      cursor: pointer;
       .goods-img {
         width: 100%;
         height: 180px;

+ 38 - 37
src/views/home/pccomponents/pages/goodsList.vue

@@ -2,27 +2,33 @@
   <div class="pcPages" :style="warpCss">
     <div :style="boxCss">
       <div class="tab-bos flex-row-start" :style="tabCss">
-        <div v-for="(item, index) in componentData.tabList" :key="index" class="tab-list flex-row-start">
+        <div v-for="(item, index) in componentData.tabList" :key="index" class="tab-list flex-row-start" @click="onTab(index)">
           <div class="tab-border" v-if="index != 0"></div>
           <div class="tab-title" :style="tabHigCss" v-if="index == componentData.tabIndex">{{ item.title || '选项卡名称' }}</div>
-          <div class="tab-title" :style="{ color: componentData.tabColor1 }" v-else>{{ item.title || '选项卡名称' }}</div>
+          <div class="tab-title hover-color" :style="{ color: componentData.tabColor1 }" v-else>{{ item.title || '选项卡名称' }}</div>
         </div>
       </div>
       <div class="goods-bos">
-        <div v-for="(item, index) in dataList" :key="index" class="goods-list flex-column-between" :style="goodsCss">
+        <div
+          v-for="(item, index) in dataList"
+          :key="index"
+          class="goods-list flex-column-between hover-color"
+          :style="goodsCss"
+          @click="onPath('/item?id=' + item.id)"
+        >
           <img
             class="goods-img"
             :src="item.productImage ? item.productImage : figure"
             alt=""
             :style="componentData.imageRadius ? { borderRadius: componentData.imageRadius + 'px' } : {}"
           />
-          <div v-if="componentData.goodsShow.includes(1)" :style="titleCss" class="itemName">{{ item.itemName || '' }}</div>
+          <div v-if="componentData.goodsShow.includes(1)" :style="titleCss" class="itemName zi-hover">{{ item.itemName || '商品名称' }}</div>
           <div class="flex-row-between">
             <div>
               <span v-if="componentData.goodsShow.includes(2)" class="memberPrice" :style="{ color: componentData.priceColor }"
-                >¥{{ item.memberPrice }}</span
+                >¥{{ item.memberPrice || '0.00' }}</span
               >
-              <span v-if="componentData.goodsShow.includes(3)" class="marketPrice">¥{{ item.marketPrice }}</span>
+              <span v-if="componentData.goodsShow.includes(3)" class="marketPrice">¥{{ item.marketPrice || '0.00' }}</span>
             </div>
             <template v-if="componentData.btnShow">
               <div v-if="componentData.btnStyle == 1" :style="btnCss1" class="btn1">{{ componentData.btnText }}</div>
@@ -41,18 +47,21 @@
 </template>
 
 <script lang="ts" setup>
+import { onPath } from '@/utils/siteConfig';
 import figure from '@/assets/images/figure.png';
-import usePcdiyStore from '@/store/modules/pcdiy';
-import { listBase } from '@/api/pmsProduct/base';
-const diyStore = usePcdiyStore();
-
-const props = defineProps<{
-  index: number; // 确保声明 index 为可选属性
+import { getDiyProductPage } from '@/api/home/diy';
+interface Props {
   row?: any;
-}>();
-const componentData = props.row ? props.row : diyStore.componentList[props.index];
+}
+const props = defineProps<Props>();
+const componentData = props.row || {};
 const dataList = ref<any>([{}, {}, {}, {}, {}]);
 
+const onTab = (index: any) => {
+  componentData.tabIndex = index;
+  getDataList();
+};
+
 onMounted(() => {
   getDataList();
 });
@@ -64,7 +73,7 @@ const getDataList = () => {
     //手动选择
     if (datas.goodsType == 1) {
       if (datas.goodsIds.length > 0) {
-        listBase({ pageNum: 1, pageSize: 20, ids: datas.goodsIds.join(',') }).then((res) => {
+        getDiyProductPage({ pageNum: 1, pageSize: 20, ids: datas.goodsIds.join(',') }).then((res) => {
           if (res.code == 200) {
             dataList.value = res.rows;
           }
@@ -72,13 +81,11 @@ const getDataList = () => {
       }
     } else if (datas.goodsType == 2) {
       //分类查询
-      if (datas.goodsClassify) {
-        listBase({
+      if (datas.categoryIds && datas.categoryIds.length > 0) {
+        getDiyProductPage({
           pageNum: 1,
-          pageSize: datas.goodsNumber == 0 ? 50 : componentData.goodsNumber,
-          topCategoryId: datas.topCategoryId,
-          mediumCategoryId: datas.mediumCategoryId,
-          bottomCategoryId: datas.bottomCategoryId
+          pageSize: componentData.goodsNumber == 0 ? 9999 : componentData.goodsNumber,
+          categoryIds: datas.categoryIds.join(',')
         }).then((res) => {
           if (res.code == 200) {
             dataList.value = res.rows;
@@ -89,22 +96,6 @@ const getDataList = () => {
   }
 };
 
-watch(
-  () => componentData.tabIndex,
-  () => {
-    console.log('tabIndex', componentData.tabIndex);
-    getDataList();
-  }
-);
-
-watch(
-  () => componentData.tabList,
-  () => {
-    getDataList();
-  },
-  { deep: true } // 5. 数组变化需要 deep 监听
-);
-
 const warpCss = computed(() => {
   let style = '';
   style += 'position:relative;';
@@ -136,6 +127,15 @@ const warpCss = computed(() => {
   if (componentData.topRounded) style += 'border-top-right-radius:' + componentData.topRounded + 'px;';
   if (componentData.bottomRounded) style += 'border-bottom-left-radius:' + componentData.bottomRounded + 'px;';
   if (componentData.bottomRounded) style += 'border-bottom-right-radius:' + componentData.bottomRounded + 'px;';
+  //间距
+  if (componentData.margin) {
+    if (componentData.margin.top > 0) {
+      style += 'margin-top:' + componentData.margin.top + 'px' + ';';
+    }
+    if (componentData.margin.bottom > 0) {
+      style += 'margin-bottom:' + componentData.margin.bottom + 'px' + ';';
+    }
+  }
 
   return style;
 });
@@ -218,6 +218,7 @@ const tabHigCss = computed(() => {
     overflow: auto;
     .tab-list {
       flex-shrink: 0;
+      cursor: pointer;
       .tab-border {
         width: 1px;
         height: 15px;

+ 23 - 35
src/views/home/pccomponents/pages/head.vue

@@ -8,6 +8,7 @@
           :src="componentData.logo ? componentData.logo : logo1"
           alt=""
           :style="{ 'width': componentData.topStyle == 1 ? '170px' : '370px' }"
+          @click="onPath('/')"
         />
         <div class="search-box">
           <div class="search-div flex-row-start">
@@ -42,7 +43,7 @@
           <img src="@/assets/images/pcdiy/layout2.png" alt="" />
           <div>全部商品分类</div>
         </div>
-        <div v-for="(item, index) in componentData.topNav" :key="index" class="nav-list" :class="index == 0 ? 'hig' : ''">
+        <div v-for="(item, index) in componentData.topNav" :key="index" class="nav-list" :class="index == 0 ? 'hig' : ''" @click="onPath(item.url)">
           {{ item.title }}
         </div>
       </div>
@@ -70,7 +71,11 @@
             :key="index"
             :class="item.id == classifyId && classifyShow ? 'classify-hig' : ''"
           >
-            <div :style="{ 'color': componentData.leftColor1 }" class="label ellipsis hover-color">
+            <div
+              @click="onPath('/search?type=1&topCategoryId=' + item.id)"
+              :style="{ 'color': componentData.leftColor1 }"
+              class="label ellipsis hover-color"
+            >
               {{ item.label }}
             </div>
             <div v-if="item.extra && item.extra.oneLable1" :style="{ 'color': componentData.leftColor2 }" class="info info1 ellipsis hover-color">
@@ -82,13 +87,15 @@
           </div>
         </div>
         <div class="classify-bos" v-if="classifyShow">
-          <div v-for="(item, index) in classifyInfo" :key="index" class="classify-item">
+          <div v-for="(item, index) in classifyInfo" :key="index" class="classify-item" @click="onPath('/search?type=2&middleCategoryId=' + item.id)">
             <div class="two-level ellipsis">{{ item.label || '' }}</div>
             <el-icon class="classify-icon" :size="14" color="#364153">
               <ArrowRight />
             </el-icon>
             <div class="classify-label">
-              <div v-for="(item1, index1) in item.children" :key="index1">{{ item1.label || '' }}</div>
+              <div @click="onPath('/search?type=3&bottomCategoryId=' + item1.id)" v-for="(item1, index1) in item.children" :key="index1">
+                {{ item1.label || '' }}
+              </div>
             </div>
           </div>
         </div>
@@ -118,7 +125,7 @@
           >
             <el-carousel :height="componentData.advertNum == 0 ? '540px' : '400px'" arrow="always">
               <template v-if="componentData.carouselList && componentData.carouselList.length > 0">
-                <el-carousel-item v-for="item in componentData.carouselList" :key="item">
+                <el-carousel-item v-for="item in componentData.carouselList" :key="item" @ckick="onPath(item.url)">
                   <el-image
                     style="width: 100%; height: 100%"
                     :src="item.imageUrl ? item.imageUrl : figure"
@@ -134,8 +141,8 @@
             </el-carousel>
           </div>
           <div class="head-box" v-if="componentData.advertNum != 0">
-            <template v-for="(item, index) in diyStore.editComponent.advertList" :key="index">
-              <div class="head-item" v-if="item.show">
+            <template v-for="(item, index) in componentData.advertList" :key="index">
+              <div class="head-item" v-if="item.show" @click="onPath(item.url)">
                 <el-image
                   style="width: 100%; height: 100%"
                   :src="item.imageUrl ? item.imageUrl : figure"
@@ -188,12 +195,12 @@
           <div class="real-time">
             <div class="real-title flex-row-between">
               <div class="real1">优易资讯</div>
-              <div class="real2 flex-row-start">
+              <!-- <div class="real2 flex-row-start">
                 <div class="hover-color">更多</div>
                 <el-icon :size="13" color="#83899F">
                   <ArrowRight />
                 </el-icon>
-              </div>
+              </div> -->
             </div>
             <template v-for="(item, index) in realList" :key="index">
               <div
@@ -208,7 +215,7 @@
           <div class="interests">
             <div class="interests-title">企业会员权益</div>
             <div class="interests-bos">
-              <div v-for="(item, index) in componentData.navlList" :key="index" class="interests-item flex-column-center">
+              <div v-for="(item, index) in componentData.navlList" :key="index" class="interests-item flex-column-center" @click="onPath(item.url)">
                 <el-image
                   class="img"
                   :src="item.imageUrl ? item.imageUrl : figure"
@@ -229,31 +236,7 @@ import figure from '@/assets/images/figure.png';
 import logo1 from '@/assets/images/pcdiy/logo1.png';
 import logo2 from '@/assets/images/pcdiy/logo2.png';
 import code from '@/assets/images/pcdiy/code.png';
-import {
-  getProductCategoryTree,
-  getHomeAdList,
-  getYouYiZiXunPage,
-  getEnterpriseMemberEquityList,
-  getHomeThreeAdList,
-  getHotSchemeTitle,
-  getHotSchemeList,
-  getScenePurchaseTitle,
-  getScenePurchaseList,
-  getPlatformFlashSaleTitle,
-  getPlatformFlashSaleList,
-  getPlatformFlashSaleBrand,
-  getExpertSelectionTitle,
-  getProcurementTopicsList,
-  getPurchaseGuideTitle,
-  getExpertSelectionList,
-  getClassificationFloorList,
-  getClassificationFloorDetail,
-  getClassificationFloorLabel,
-  getClassificationFloorDetail2,
-  getProjectCaseTitle,
-  getProjectCaseList,
-  countOrder
-} from '@/api/home/index';
+import { getProductCategoryTree, countOrder } from '@/api/home/index';
 import { getAnnouncementPage } from '@/api/home/diy';
 import { onPath } from '@/utils/siteConfig';
 import Cookies from 'js-cookie';
@@ -360,6 +343,10 @@ const warpCss = computed(() => {
 
   return style;
 });
+
+const onPath2 = (row: any) => {
+  console.log(row, '?????');
+};
 </script>
 
 <style lang="scss" scoped>
@@ -384,6 +371,7 @@ const warpCss = computed(() => {
       border-radius: 4px;
       margin-top: 10px;
       margin-right: 30px;
+      cursor: pointer;
     }
 
     .search-box {

+ 13 - 15
src/views/home/pccomponents/pages/hot.vue

@@ -3,7 +3,7 @@
     <el-image class="hot-image" :src="componentData.imageUrl ? componentData.imageUrl : figure" fit="fill" />
     <div
       @click="onClick(mapItem)"
-      class="absolute hot-aaaaaa"
+      class="absolute"
       v-for="(mapItem, mapIndex) in componentData.heatMapData"
       :key="mapIndex"
       :style="{ width: mapItem.width + '%', height: mapItem.height + '%', left: mapItem.left + '%', top: mapItem.top + '%' }"
@@ -12,17 +12,18 @@
 </template>
 
 <script lang="ts" setup>
-import usePcdiyStore from '@/store/modules/pcdiy';
+import { onPath } from '@/utils/siteConfig';
 import figure from '@/assets/images/figure.png';
-const diyStore = usePcdiyStore();
-
-const props = defineProps<{
-  index: number; // 确保声明 index 为可选属性
+interface Props {
   row?: any;
-}>();
+}
 
-const onClick = (mapItem: any) => {};
-const componentData = props.row ? props.row : diyStore.componentList[props.index];
+const props = defineProps<Props>();
+const onClick = (mapItem: any) => {
+  onPath(mapItem.link);
+  console.log('mapItem', mapItem);
+};
+const componentData = props.row || {};
 
 const warpCss = computed(() => {
   let style = '';
@@ -77,13 +78,10 @@ const warpCss = computed(() => {
 
   .hot-image {
     width: 100%;
-
-
   }
 
-  .hot-aaaaaa {
-      border: 1px red solid;
-      z-index: 10;
-    }
+  .absolute {
+    cursor: pointer;
+  }
 }
 </style>

+ 2 - 1
src/views/home/pccomponents/pages/imageCube.vue

@@ -2,7 +2,7 @@
   <div class="pcPages" :style="warpCss">
     <div class="imageCube-bos" :style="{ gap: componentData.gap + 'px' }">
       <template v-for="(item, index) in componentData.imagelList" :key="index">
-        <div v-if="index < componentData.number" class="imageCube-list" :style="boxCss">
+        <div v-if="index < componentData.number" class="imageCube-list" :style="boxCss" @click="onPath(item.url)">
           <el-image
             class="img"
             :src="item.imageUrl ? item.imageUrl : figure"
@@ -16,6 +16,7 @@
 </template>
 
 <script lang="ts" setup>
+import { onPath } from '@/utils/siteConfig';
 import figure from '@/assets/images/figure.png';
 interface Props {
   row?: any;

+ 15 - 2
src/views/home/pccomponents/pages/navigation.vue

@@ -4,7 +4,13 @@
       <el-carousel :height="170 * componentData.count + (componentData.count == 2 ? 10 : 0) + 'px'" :autoplay="false" arrow="always">
         <el-carousel-item v-for="(item1, index1) in dataList" :key="index1" class="w100% h100%">
           <div class="carousel-list">
-            <div v-for="(item, index) in item1" :key="index" class="data-list flex-column-center hover-color" :style="boxCss">
+            <div
+              v-for="(item, index) in item1"
+              :key="index"
+              class="data-list flex-column-center hover-color"
+              :style="boxCss"
+              @click="onPath(item.url)"
+            >
               <div :style="titleCss" class="zi-hover">{{ item.title || '' }}</div>
               <div :style="subtitleCss" class="mt-[2px] mb-[12px]">{{ item.subtitle || '' }}</div>
               <el-image
@@ -19,7 +25,13 @@
       </el-carousel>
     </div>
     <div v-else :style="warpCss" class="data-bos">
-      <div v-for="(item, index) in componentData.navlList" :key="index" class="data-list flex-column-center hover-color" :style="boxCss">
+      <div
+        v-for="(item, index) in componentData.navlList"
+        :key="index"
+        class="data-list flex-column-center hover-color"
+        :style="boxCss"
+        @click="onPath(item.url)"
+      >
         <div :style="titleCss" class="zi-hover">{{ item.title || '' }}</div>
         <div :style="subtitleCss" class="mt-[2px] mb-[12px]">{{ item.subtitle || '' }}</div>
         <el-image
@@ -34,6 +46,7 @@
 </template>
 
 <script lang="ts" setup>
+import { onPath } from '@/utils/siteConfig';
 import figure from '@/assets/images/figure.png';
 interface Props {
   row?: any;

+ 18 - 16
src/views/home/pccomponents/pages/textTitle.vue

@@ -3,29 +3,29 @@
     <div :style="warpCss">
       <!-- 风格1 -->
       <div :style="boxCss" v-if="componentData.styleType == 1">
-        <div class="hover-color" :style="titleCss">{{ componentData.title }}{{ componentData.titleUrl }}</div>
+        <div @click="onPath(componentData.titleUrl)" class="hover-color" :style="titleCss">{{ componentData.title }}{{ componentData.titleUrl }}</div>
       </div>
       <!-- 风格2 -->
       <div :style="boxCss" class="style2 flex-row-center" v-else-if="componentData.styleType == 2">
         <div class="style2-border" :style="{ backgroundColor: componentData.titleColor }"></div>
-        <div class="style2-text hover-color" :style="titleCss">{{ componentData.title }}</div>
+        <div @click="onPath(componentData.titleUrl)" class="style2-text hover-color" :style="titleCss">{{ componentData.title }}</div>
         <div class="style2-border" :style="{ backgroundColor: componentData.titleColor }"></div>
       </div>
       <!-- 风格3 -->
       <div :style="boxCss" class="style3 flex-column-center" v-else-if="componentData.styleType == 3">
-        <div :style="titleCss" class="mb-[4px] hover-color">{{ componentData.title }}</div>
+        <div @click="onPath(componentData.titleUrl)" :style="titleCss" class="mb-[4px] hover-color">{{ componentData.title }}</div>
         <div class="style3-border" :style="{ backgroundColor: componentData.titleColor }"></div>
         <div class="style3-jiao" :style="{ borderColor: componentData.titleColor }"></div>
       </div>
       <!-- 风格4 -->
       <div :style="boxCss" class="style4 flex-column-center" v-else-if="componentData.styleType == 4">
-        <div :style="titleCss" class="mb-[4px] hover-color">{{ componentData.title }}</div>
+        <div @click="onPath(componentData.titleUrl)" :style="titleCss" class="mb-[4px] hover-color">{{ componentData.title }}</div>
         <div class="style4-border1" :style="{ backgroundColor: componentData.titleColor }"></div>
         <div class="style4-border2" :style="{ backgroundColor: componentData.titleColor }"></div>
       </div>
       <!-- 风格5 -->
       <div :style="boxCss" class="style5 flex-column-center" v-else-if="componentData.styleType == 5">
-        <div :style="titleCss" class="mb-[4px] hover-color">{{ componentData.title }}</div>
+        <div @click="onPath(componentData.titleUrl)" :style="titleCss" class="mb-[4px] hover-color">{{ componentData.title }}</div>
         <div class="flex-row-center">
           <div class="style5-border" :style="{ backgroundColor: componentData.titleColor }"></div>
           <div class="style5-box" :style="{ borderColor: componentData.titleColor }"></div>
@@ -36,34 +36,34 @@
       <div :style="boxCss" class="style6 flex-column-center" v-else-if="componentData.styleType == 6">
         <div class="style6-bos flex-row-center" :style="{ borderColor: componentData.titleColor }">
           <div class="style6-border style6-border1" :style="{ backgroundColor: componentData.titleColor }"></div>
-          <div :style="titleCss" class="style6-box hover-color">{{ componentData.title }}</div>
+          <div @click="onPath(componentData.titleUrl)" :style="titleCss" class="style6-box hover-color">{{ componentData.title }}</div>
           <div class="style6-border style6-border2" :style="{ backgroundColor: componentData.titleColor }"></div>
         </div>
       </div>
       <!-- 风格7 -->
       <div :style="boxCss" class="style7 flex-column-center" v-else-if="componentData.styleType == 7">
         <div class="style7-bos">
-          <div class="style7-text hover-color" :style="titleCss">{{ componentData.title }}</div>
+          <div @click="onPath(componentData.titleUrl)" class="style7-text hover-color" :style="titleCss">{{ componentData.title }}</div>
           <div class="style7-line" :style="{ borderColor: componentData.titleColor }"></div>
         </div>
       </div>
       <!-- 风格8 -->
       <div :style="boxCss" class="style8 flex-column-center" v-else-if="componentData.styleType == 8">
         <div class="style8-bos">
-          <div class="style8-text hover-color" :style="titleCss">{{ componentData.title }}</div>
+          <div @click="onPath(componentData.titleUrl)" class="style8-text hover-color" :style="titleCss">{{ componentData.title }}</div>
           <div class="style8-line" :style="{ borderColor: componentData.titleColor }"></div>
         </div>
       </div>
       <!-- 风格9 -->
       <div :style="boxCss" class="style9 flex-row-start" v-else-if="componentData.styleType == 9">
         <div class="style9-border" :style="{ backgroundColor: componentData.titleColor }"></div>
-        <div class="pl-[10px] hover-color" :style="titleCss">{{ componentData.title }}</div>
+        <div @click="onPath(componentData.titleUrl)" class="pl-[10px] hover-color" :style="titleCss">{{ componentData.title }}</div>
       </div>
       <!-- 风格10 -->
       <div :style="boxCss" class="style10 flex-column-center" v-else-if="componentData.styleType == 10">
         <div class="style10-bos flex-row-start">
           <img class="style10-img1" src="@/assets/images/pcdiy/style10-1.png" alt="" />
-          <div :style="titleCss" class="hover-color">{{ componentData.title }}</div>
+          <div @click="onPath(componentData.titleUrl)" :style="titleCss" class="hover-color">{{ componentData.title }}</div>
           <img class="style10-img2" src="@/assets/images/pcdiy/style10-2.png" alt="" />
         </div>
         <div class="mt-[2px]" :style="subtitleCss">
@@ -74,7 +74,7 @@
       <div :style="boxCss" class="style11 flex-column-center" v-else-if="componentData.styleType == 11">
         <div class="style11-bos flex-row-start">
           <img class="style11-img style11-img1" src="@/assets/images/pcdiy/style11-1.png" alt="" />
-          <div :style="titleCss" class="style11-text hover-color">{{ componentData.title }}</div>
+          <div @click="onPath(componentData.titleUrl)" :style="titleCss" class="style11-text hover-color">{{ componentData.title }}</div>
           <img class="style11-img style11-img2" src="@/assets/images/pcdiy/style11-2.png" alt="" />
           <img class="style11-img3" src="@/assets/images/pcdiy/style11-3.png" alt="" />
         </div>
@@ -85,10 +85,10 @@
       <!-- 风格12 -->
       <div :style="boxCss" class="style12 flex-row-between" v-else-if="componentData.styleType == 12">
         <div class="flex-row-start">
-          <div :style="titleCss" class="hover-color">{{ componentData.title }}</div>
+          <div @click="onPath(componentData.titleUrl)" :style="titleCss" class="hover-color">{{ componentData.title }}</div>
           <div :style="subtitleCss" class="ml-[5px]">{{ componentData.subtitle }}</div>
         </div>
-        <div v-if="componentData.moreShow" class="flex-row-start hover-color" :style="moreCss">
+        <div v-if="componentData.moreShow" class="flex-row-start hover-color" :style="moreCss" @click="onPath(componentData.moreUrl)">
           <div>{{ componentData.more }}</div>
           <el-icon><ArrowRight /></el-icon>
         </div>
@@ -97,17 +97,17 @@
       <div :style="boxCss" class="style13 flex-column-center" v-else-if="componentData.styleType == 13">
         <div class="style13-bos flex-row-start">
           <img class="style13-img1" src="@/assets/images/pcdiy/style13-1.png" alt="" />
-          <div :style="titleCss" class="hover-color">{{ componentData.title }}</div>
+          <div @click="onPath(componentData.titleUrl)" :style="titleCss" class="hover-color">{{ componentData.title }}</div>
           <img class="style13-img2" src="@/assets/images/pcdiy/style13-2.png" alt="" />
         </div>
       </div>
       <!-- 风格14 -->
       <div :style="boxCss" class="style14 flex-row-between" v-else-if="componentData.styleType == 14">
         <div>
-          <div :style="titleCss" class="hover-color">{{ componentData.title }}</div>
+          <div @click="onPath(componentData.titleUrl)" :style="titleCss" class="hover-color">{{ componentData.title }}</div>
           <div :style="subtitleCss">{{ componentData.subtitle }}</div>
         </div>
-        <div v-if="componentData.moreShow" class="flex-row-start hover-color" :style="moreCss">
+        <div v-if="componentData.moreShow" class="flex-row-start hover-color" :style="moreCss" @click="onPath(componentData.moreUrl)">
           <div>{{ componentData.more }}</div>
           <el-icon><ArrowRight /></el-icon>
         </div>
@@ -117,6 +117,8 @@
 </template>
 
 <script setup name="Index" lang="ts">
+import { onPath } from '@/utils/siteConfig';
+
 interface Props {
   row?: any;
 }

+ 23 - 20
src/views/item/index.vue

@@ -4,7 +4,7 @@
       <div class="head-left">
         <div class="left-carousel" v-if="carousel && carousel.length > 0">
           <div v-for="(item, index) in carousel" :key="index" class="carousel-item" :class="carouselIndex == index ? 'hig' : ''">
-            <img :src="item" alt="" @click="onCarousel(1, index)" />
+            <img :src="item" alt="" @click="onCarousel(1, index)" @mouseenter="onCarousel(1, index)" />
           </div>
         </div>
         <div v-else class="left-carousel"></div>
@@ -20,7 +20,6 @@
         <div class="head-right flex-column-between">
           <div>
             <div class="right-title">{{ dataInfo.itemName || '' }}</div>
-            <div class="right-num">商品库存 {{ dataInfo.allStock || 0 }}套</div>
             <div class="right-price flex-row-between">
               <div class="flex-row-start">
                 <div class="price1">
@@ -57,32 +56,44 @@
                 <div class="specs-box"></div>
               </div>
               <div class="specs-list">
-                <div>单位</div>
+                <div>规格/型号</div>
                 <div class="specs-item hig">
-                  {{ dataInfo.unitName }}
+                  {{ dataInfo.specificationsCode }}
                 </div>
                 <div class="specs-box"></div>
               </div>
               <div class="specs-list">
-                <div>规格型号</div>
+                <div>UPC(69)条码</div>
                 <div class="specs-item hig">
-                  {{ dataInfo.specification }}
+                  {{ dataInfo.upcBarcode }}
                 </div>
                 <div class="specs-box"></div>
               </div>
               <div class="specs-list">
-                <div>UPC(69)条码</div>
+                <div>定制</div>
                 <div class="specs-item hig">
-                  {{ dataInfo.upcBarcode }}
+                  {{ dataInfo.isCustomize == 1 ? '可定制' : '不可定制' }}
                 </div>
                 <div class="specs-box"></div>
               </div>
+              <div class="specs-list">
+                <div>供货时间</div>
+                <div class="specs-item hig">
+                  {{ dataInfo.deliveryTime || '' }}
+                </div>
+                <div class="specs-box"></div>
+              </div>
+              <div class="specs-list">
+                <div>商品库存</div>
+                <div class="specs-item hig">{{ dataInfo.allStock || 0 }} {{ dataInfo.unitName }}</div>
+                <div class="specs-box"></div>
+              </div>
             </div>
             <div class="number-bos">
               <div>数量</div>
               <div class="flex-row-start number-box">
-                <el-input-number v-model="num" :min="1" :max="dataInfo.allStock" @change="handleChange" />
-                <div style="margin-left: 10px">提示:本产品起订为:{{ dataInfo.minOrderQuantity }}台</div>
+                <el-input-number v-model="num" :min="dataInfo.minOrderQuantity" :max="dataInfo.allStock" />
+                <div style="margin-left: 10px">提示:本产品起订为:{{ dataInfo.minOrderQuantity }}{{ dataInfo.unitName }}</div>
               </div>
             </div>
           </div>
@@ -244,7 +255,9 @@ const getInfo = () => {
           carousel.value = carousel.value.slice(0, 5);
         }
       }
+      num.value = Number(res.data.minOrderQuantity || 1);
       dataInfo.value = res.data;
+      dataInfo.value.minOrderQuantity = num.value;
       dataInfo.value.allStock = Number(res.data.totalInventory || 0) + Number(res.data.nowInventory || 0) + Number(res.data.virtualInventory || 0);
     }
   });
@@ -307,16 +320,6 @@ const onCarousel = (type: number, index?: any) => {
   }
 };
 
-const handleChange = (val: any) => {
-  const numberVal = Number(val);
-  const step = dataInfo.value.minOrderQuantity || 1;
-  num.value = Math.floor(numberVal / step) * step;
-  // if (val > num.value) {
-  //   num.value = Math.ceil(numberVal / step) * step;
-  // } else {
-  //   num.value = Math.floor(numberVal / step) * step;
-  // }
-};
 import { cartStore } from '@/store/modules/cart';
 const cart = cartStore();
 const onCart = () => {

+ 12 - 3
src/views/search/index.vue

@@ -111,6 +111,16 @@
         </el-checkbox-group>
       </div>
     </div>
+    <!-- 游标分页控制 -->
+    <pagination
+      v-show="dataList.length > 0"
+      v-model:page="httpObj.pageNum"
+      v-model:limit="httpObj.pageSize"
+      v-model:way="way"
+      :cursor-mode="true"
+      :has-more="hasMore"
+      @pagination="getList"
+    />
     <!-- 商品 -->
     <div class="expert-bos">
       <div v-for="(item, index) in dataList" :key="index" class="expert-list" @click="onPath('/item?id=' + item.id)">
@@ -121,8 +131,8 @@
           <span class="marketPrice">¥{{ item.marketPrice }}</span>
         </div>
       </div>
-      <div class="empty-bos">
-        <el-empty v-if="dataList.length === 0" description="暂无数据" />
+      <div class="empty-bos" v-if="dataList.length === 0">
+        <el-empty description="暂无数据" />
       </div>
     </div>
     <!-- 游标分页控制 -->
@@ -432,7 +442,6 @@ onMounted(() => {
       width: 230px;
       height: 306px;
       background: #ffffff;
-
       padding: 20px;
       cursor: pointer;
       img {

+ 6 - 4
src/views/trad/index.vue

@@ -6,9 +6,9 @@
         <div style="margin-left: 6px">确认订单信息</div>
       </div>
       <div class="create-head flex-row-start">
-        <span>测试客户123</span>
+        <span>{{ userStore.userInfo && userStore.userInfo.user ? userStore.userInfo.user.nickName : '' }}</span>
         <span class="border"></span>
-        <!-- <span>某某部门</span> -->
+        <span>{{ userStore.userInfo && userStore.userInfo.user ? userStore.userInfo.customerName : '' }}</span>
       </div>
       <div class="address-title">
         <div>收货地址</div>
@@ -33,7 +33,7 @@
         <!-- <div>展开全部地址</div>
         <el-icon style="margin-left: 6px" color="#6A7282" size="14"><ArrowDown /></el-icon> -->
       </div>
-      <div class="form-bos">
+      <div class="form-bos" style="align-items: center">
         <div class="form-title flex-row-start">
           <div class="asterisk">*</div>
           <div>配送时间</div>
@@ -48,7 +48,7 @@
           :disabled-date="disabledDate"
         />
       </div>
-      <div class="form-bos">
+      <div class="form-bos" style="align-items: center">
         <div class="form-title flex-row-start">
           <div class="asterisk">*</div>
           <div>费用类型</div>
@@ -187,6 +187,8 @@ import { getAddressList, addAddress } from '@/api/pc/enterprise';
 import { shoppingCartList, pcOrdersubmit } from '@/api/goods/index';
 import { onPath } from '@/utils/siteConfig';
 import { regionData } from 'element-china-area-data';
+import { useUserStore } from '@/store/modules/user';
+const userStore = useUserStore();
 const route = useRoute();
 const ids = ref<any>('');
 const tableData = ref<any>([]);

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác