bugfix
This commit is contained in:
parent
e303b98fd1
commit
69d7fb2540
@ -51,6 +51,7 @@
|
||||
"uuid": "^9.0.0",
|
||||
"vue": "2.6.10",
|
||||
"vue-count-to": "^1.0.13",
|
||||
"vue-cropper": "^0.6.5",
|
||||
"vue-device-detector": "^1.1.6",
|
||||
"vue-infinite-scroll": "^2.0.2",
|
||||
"vue-router": "^3.0.2",
|
||||
|
||||
40
f/web-kboss/src/api/ncmatch/index.js
Normal file
40
f/web-kboss/src/api/ncmatch/index.js
Normal file
@ -0,0 +1,40 @@
|
||||
import request from "@/utils/request";
|
||||
//获取商品分类
|
||||
export function reqGetProductCategorySearch(data) {
|
||||
return request({
|
||||
url: '/product/product_category_search.dspy',
|
||||
method: 'post',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
data
|
||||
})
|
||||
}
|
||||
//添加产品 publish_product_add
|
||||
export function reqPublishProductAdd(data) {
|
||||
return request({
|
||||
url: '/product/publish_product_add.dspy',
|
||||
method: 'post',
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
data
|
||||
})
|
||||
}
|
||||
//获公司类型 /product/company_category_search.dspy
|
||||
export function reqCompanyCategorySearch(data) {
|
||||
return request({
|
||||
url: '/product/company_category_search.dspy',
|
||||
method: 'post',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
//获取全部产品/product/publish_product_search_first_page.dspy
|
||||
export function reqPublishProductSearchFirstPage(data) {
|
||||
return request({
|
||||
url: '/product/publish_product_search_first_page.dspy',
|
||||
method: 'post',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
data
|
||||
})
|
||||
}
|
||||
@ -175,6 +175,13 @@ export const constantRoutes = [
|
||||
hidden: true,
|
||||
meta: {title: "首页", fullPath: "/ncmatch/mainPage/index"},
|
||||
},
|
||||
{
|
||||
path: "supplyAndDemandSquare",
|
||||
component: () => import("@/views/homePage/ncmatch/supplyAndDemandSquare/index.vue"),
|
||||
name: "supplyAndDemandSquare",
|
||||
hidden: true,
|
||||
meta: {title: "算力供需广场", fullPath: "/ncmatch/supplyAndDemandSquare"},
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@ -4,14 +4,13 @@
|
||||
<div class="centerBox">
|
||||
<span style="margin-top: 100px" class="title">
|
||||
|
||||
<span v-if=" JSON.stringify(logoInfoNew)!=='{}'" class="leftText">
|
||||
{{ logoInfoNew.home.bannerTitle || "" }}
|
||||
</span>
|
||||
<span v-if="JSON.stringify(logoInfoNew) !== '{}'" class="leftText">
|
||||
{{ logoInfoNew.home.bannerTitle || "" }}
|
||||
</span>
|
||||
|
||||
|
||||
|
||||
<span
|
||||
class="rightText"> 您身边的AI管家</span></span>
|
||||
<span class="rightText"> 您身边的AI管家</span></span>
|
||||
<!-- <span class="description">支持模型训练、推理和数据处理,灵活配置,助您高效释放AI潜能</span>-->
|
||||
<ul style="margin-top: 50px" class="tagUl">
|
||||
<li>全 球 领 先 的 AI 服 务 运 营 商</li>
|
||||
@ -20,33 +19,31 @@
|
||||
</ul>
|
||||
</div>
|
||||
<div style="cursor: pointer" class="tag">
|
||||
<span @click="openTalk" class="product">
|
||||
<span class="productName">4090 裸金属</span>
|
||||
<span class="price"><span class="smallText">¥</span> <span class="bigText">6000</span> <span
|
||||
<span @click="openTalk" class="product">
|
||||
<span class="productName">4090 裸金属</span>
|
||||
<span class="price"><span class="smallText">¥</span> <span class="bigText">6000</span> <span
|
||||
class="smallText">/台/月</span> </span>
|
||||
</span>
|
||||
</span>
|
||||
<span @click="goBaiduFn" style="top: 180px" class="product">
|
||||
<span class="productName">云资源</span>
|
||||
<span class="price">
|
||||
<span class="productName">云资源</span>
|
||||
<span class="price">
|
||||
|
||||
<span
|
||||
style="margin-top: 15px"
|
||||
class="smallText">直降 <span style="font-size: 30px;display: inline-block"
|
||||
class="bigText">20%</span></span> </span>
|
||||
</span>
|
||||
<span style="margin-top: 15px" class="smallText">直降 <span style="font-size: 30px;display: inline-block"
|
||||
class="bigText">20%</span></span> </span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="base">
|
||||
<div class="bg"></div>
|
||||
<div class="itemTitle">
|
||||
<span class="topText"> <span>云筑</span><span class="commonTextColor">企业基座</span></span>
|
||||
<span class="topText"> <span>云筑</span><span class="commonTextColor">企业基座</span></span>
|
||||
<span class="bottomText">多云融合 让上云更简单</span>
|
||||
</div>
|
||||
|
||||
<ul class="myTab">
|
||||
<li v-for="menu in baseMenu" :class="currentBaseMenu ===menu.id?'activeMenu':''" @click="clickBaseMenu(menu)"
|
||||
:key="menu.name">
|
||||
<img :src="currentBaseMenu ===menu.id?menu.icon:menu.activeIcon" alt=""> {{ menu.name }}
|
||||
<li v-for="menu in baseMenu" :class="currentBaseMenu === menu.id ? 'activeMenu' : ''" @click="clickBaseMenu(menu)"
|
||||
:key="menu.name">
|
||||
<img :src="currentBaseMenu === menu.id ? menu.icon : menu.activeIcon" alt=""> {{ menu.name }}
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
@ -54,17 +51,14 @@
|
||||
<span class="title">{{ baseItem.title }}</span>
|
||||
<p style="line-height: 2" class="description">{{ baseItem.description }}</p>
|
||||
<ul class="itemContentTag">
|
||||
<li v-for="(item,index) in baseItem.list" :key="index">
|
||||
<img :src="item.icon" alt=""><span v-if="item.name"
|
||||
:style="item.name === '高可靠' ? { width: '150px' } : {}"
|
||||
class="tagTitle">{{ item.name }}</span> <span
|
||||
class="tagContent">{{ item.content }}</span>
|
||||
<li v-for="(item, index) in baseItem.list" :key="index">
|
||||
<img :src="item.icon" alt=""><span v-if="item.name" :style="item.name === '高可靠' ? { width: '150px' } : {}"
|
||||
class="tagTitle">{{ item.name }}</span> <span class="tagContent">{{ item.content }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
<span class="basePrice"><span style="font-weight: bold;">¥</span><span
|
||||
style="font-weight: bold;font-size: 48px">{{ baseItem.price }}</span>
|
||||
<span
|
||||
style="color: #7A82A0">/{{ baseItem.price_unit }}</span>
|
||||
style="font-weight: bold;font-size: 48px">{{ baseItem.price }}</span>
|
||||
<span style="color: #7A82A0">/{{ baseItem.price_unit }}</span>
|
||||
<!-- <span-->
|
||||
<!-- style="color: #7A82A0;text-decoration-line: line-through">¥{{ baseItem.pre_price }}/{{-->
|
||||
<!-- baseItem.price_unit-->
|
||||
@ -72,50 +66,47 @@
|
||||
</span>
|
||||
<div class="twoBtn">
|
||||
<div class="butStyle" @click="goBaiduFn(baseItem)">立即购买 <span
|
||||
style="display: inline-block;margin-left: 5px;color: white">></span>
|
||||
style="display: inline-block;margin-left: 5px;color: white">></span>
|
||||
|
||||
|
||||
</div>
|
||||
<div v-show="false" class="lookDetailStyle">查看详情 > <span
|
||||
style="display: inline-block;margin-left: 5px;"></span>
|
||||
style="display: inline-block;margin-left: 5px;"></span>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<span class="discountStyle"><span style="font-size: 18px">官网折扣</span> <span
|
||||
style="font-size: 24px">{{ baseItem.discount }}折</span></span>
|
||||
<span class="discountStyle"><span style="font-size: 18px">官网折扣</span> <span style="font-size: 24px">{{
|
||||
baseItem.discount }}折</span></span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="suan">
|
||||
<div class="bg"></div>
|
||||
<div class="itemTitle">
|
||||
<span class="topText"> <span>智算</span><span class="commonTextColor">未来征程</span></span>
|
||||
<span class="topText"> <span>智算</span><span class="commonTextColor">未来征程</span></span>
|
||||
<span class="bottomText">多元异构 灵活短租</span>
|
||||
</div>
|
||||
|
||||
<ul class="myTab">
|
||||
<li v-for="menu in suanMenu" :class="currentSuanMenu ===menu.id?'activeMenu':''" @click="clickSuanMenu(menu)"
|
||||
:key="menu.name">
|
||||
<img :src="currentSuanMenu ===menu.id?menu.icon:menu.activeIcon" alt=""> {{ menu.name }}
|
||||
<li v-for="menu in suanMenu" :class="currentSuanMenu === menu.id ? 'activeMenu' : ''" @click="clickSuanMenu(menu)"
|
||||
:key="menu.name">
|
||||
<img :src="currentSuanMenu === menu.id ? menu.icon : menu.activeIcon" alt=""> {{ menu.name }}
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
<div class="itemContentSuan">
|
||||
<span class="title">{{ suanItem.title }}</span>
|
||||
<ul class="itemContentTag">
|
||||
<li v-for="(item,index) in suanItem.list" :key="index">
|
||||
<img :src="item.icon" alt=""><span v-if="item.name"
|
||||
:style="item.name === '高可靠' ? { width: '150px' } : {}"
|
||||
class="tagTitle">{{ item.name }}</span> <span
|
||||
class="tagContent">{{ item.content }}</span>
|
||||
<li v-for="(item, index) in suanItem.list" :key="index">
|
||||
<img :src="item.icon" alt=""><span v-if="item.name" :style="item.name === '高可靠' ? { width: '150px' } : {}"
|
||||
class="tagTitle">{{ item.name }}</span> <span class="tagContent">{{ item.content }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<span class="basePrice"><span style="font-weight: bold;">¥</span><span
|
||||
style="font-weight: bold;font-size: 48px">{{ suanItem.price }}</span>
|
||||
<span
|
||||
style="color: #7A82A0">/{{ suanItem.price_unit }}</span>
|
||||
style="font-weight: bold;font-size: 48px">{{ suanItem.price }}</span>
|
||||
<span style="color: #7A82A0">/{{ suanItem.price_unit }}</span>
|
||||
<!-- <span-->
|
||||
<!-- style="color: #7A82A0;text-decoration-line: line-through">¥{{ suanItem.pre_price }}/{{-->
|
||||
<!-- suanItem.price_unit-->
|
||||
@ -130,12 +121,12 @@
|
||||
<!-- </span>-->
|
||||
<div style="margin-top: 10px!important;" class="twoBtn">
|
||||
<div class="butStyle" @click="openTalk">立即咨询 <span
|
||||
style="display: inline-block;margin-left: 5px;color: white">></span>
|
||||
style="display: inline-block;margin-left: 5px;color: white">></span>
|
||||
|
||||
|
||||
</div>
|
||||
<div v-show="false" class="lookDetailStyle">查看详情 > <span
|
||||
style="display: inline-block;margin-left: 5px;"></span>
|
||||
style="display: inline-block;margin-left: 5px;"></span>
|
||||
|
||||
|
||||
</div>
|
||||
@ -146,13 +137,13 @@
|
||||
<div class="net">
|
||||
<div class="bg"></div>
|
||||
<div class="itemTitle">
|
||||
<span class="topText"> <span>网织</span><span class="commonTextColor">智能经纬</span></span>
|
||||
<span class="topText"> <span>网织</span><span class="commonTextColor">智能经纬</span></span>
|
||||
<span class="bottomText">云算网融合 让连接更简单</span>
|
||||
</div>
|
||||
<ul class="myTab">
|
||||
<li v-for="menu in netMenu" :class="currentNetMenu ===menu.id?'activeMenu':''" @click="clickNetMenu(menu)"
|
||||
:key="menu.name">
|
||||
<img :src="currentBaseMenu ===menu.id?menu.icon:menu.activeIcon" alt=""> {{ menu.name }}
|
||||
<li v-for="menu in netMenu" :class="currentNetMenu === menu.id ? 'activeMenu' : ''" @click="clickNetMenu(menu)"
|
||||
:key="menu.name">
|
||||
<img :src="currentBaseMenu === menu.id ? menu.icon : menu.activeIcon" alt=""> {{ menu.name }}
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
@ -161,30 +152,29 @@
|
||||
<p style="line-height: 2;margin-bottom: 15px" class="description">{{ netItem.description }}</p>
|
||||
<span class="subTitle">产品优势</span>
|
||||
<ul s class="itemContentTag">
|
||||
<li v-for="(item,index) in netItem.advantageList" :key="index">
|
||||
<li v-for="(item, index) in netItem.advantageList" :key="index">
|
||||
<img :src="item.icon" alt=""><span style="width: fit-content!important;" class="tagTitle">{{
|
||||
item.name
|
||||
}}</span> <span
|
||||
class="tagContent">{{ item.content }}</span>
|
||||
}}</span> <span class="tagContent">{{ item.content }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
<span class="subTitle">应用场景</span>
|
||||
<ul class="netTagUl">
|
||||
<li v-for="(i,d) in netItem.tagList" :key="d">{{ i.name }}</li>
|
||||
<li v-for="(i, d) in netItem.tagList" :key="d">{{ i.name }}</li>
|
||||
</ul>
|
||||
<div class="twoBtn">
|
||||
<div @click="openTalk" class="butStyle">立即咨询 <span
|
||||
style="display: inline-block;margin-left: 5px;color: white">></span>
|
||||
style="display: inline-block;margin-left: 5px;color: white">></span>
|
||||
|
||||
|
||||
</div>
|
||||
<div @click="goDetail(netItem.id)" class="lookDetailStyle">查看详情 > <span
|
||||
style="display: inline-block;margin-left: 5px;"></span>
|
||||
style="display: inline-block;margin-left: 5px;"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top: 80px;margin-bottom: 50px" class="itemTitle">
|
||||
<span class="topText"> <span></span><span class="commonTextColor">合作伙伴</span></span>
|
||||
<span class="topText"> <span></span><span class="commonTextColor">合作伙伴</span></span>
|
||||
</div>
|
||||
<div style="max-width:1400px;padding: 15px;width: 100%;background: white;border-radius: 16px;margin-bottom: 30px">
|
||||
<logo-g></logo-g>
|
||||
@ -195,7 +185,7 @@
|
||||
<div class="bg"></div>
|
||||
|
||||
<div style="margin-top: 140px" class="itemTitle">
|
||||
<span class="topText"> <span>算力</span><span class="commonTextColor">资源</span></span>
|
||||
<span class="topText"> <span>算力</span><span class="commonTextColor">资源</span></span>
|
||||
</div>
|
||||
<div class="mapBox">
|
||||
<div style="display: flex;justify-content: space-around;width: 100%;">
|
||||
@ -227,8 +217,8 @@
|
||||
<li>
|
||||
<div style="display: flex;flex-direction: column;align-items: flex-start">
|
||||
<span class="numberStyle">8
|
||||
<span class="mapTag">+</span>
|
||||
</span>
|
||||
<span class="mapTag">+</span>
|
||||
</span>
|
||||
<span style="color: #222F60;font-size: 18px;margin-top: 5px">算力中心接入</span>
|
||||
</div>
|
||||
</li>
|
||||
@ -251,16 +241,16 @@
|
||||
<li>
|
||||
<div style="display: flex;flex-direction: column;align-items: flex-start">
|
||||
<span class="numberStyle">2000
|
||||
<span style="right: -35px" class="mapTag">P+</span>
|
||||
</span>
|
||||
<span style="right: -35px" class="mapTag">P+</span>
|
||||
</span>
|
||||
<span style="color: #222F60;font-size: 18px;margin-top: 5px">算力</span>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div style="display: flex;flex-direction: column;align-items: flex-start">
|
||||
<span class="numberStyle">10
|
||||
<span style="right: -35px" class="mapTag">ms</span>
|
||||
</span>
|
||||
<span style="right: -35px" class="mapTag">ms</span>
|
||||
</span>
|
||||
<span style="color: #222F60;font-size: 18px;margin-top: 5px">实时算力响应</span>
|
||||
</div>
|
||||
</li>
|
||||
@ -269,8 +259,8 @@
|
||||
<li>
|
||||
<div style="display: flex;flex-direction: column;align-items: flex-start">
|
||||
<span class="numberStyle">100,000
|
||||
<span class="mapTag">+</span>
|
||||
</span>
|
||||
<span class="mapTag">+</span>
|
||||
</span>
|
||||
<span style="color: #222F60;font-size: 18px;margin-top: 5px">注册用户</span>
|
||||
</div>
|
||||
</li>
|
||||
@ -289,8 +279,8 @@
|
||||
<el-input v-model="phone" placeholder="请输入您的手机号" class="custom-input">
|
||||
<template #append>
|
||||
<span @click="$router.push({
|
||||
path:'/login',
|
||||
phone
|
||||
path: '/login',
|
||||
phone
|
||||
})" class="experience-btn">立即体验</span>
|
||||
</template>
|
||||
</el-input>
|
||||
@ -299,21 +289,13 @@
|
||||
|
||||
|
||||
<Talk></Talk>
|
||||
<el-dialog
|
||||
title=""
|
||||
|
||||
:visible.sync="mesDialog"
|
||||
custom-class="msgDialog"
|
||||
:before-close="handleClose"
|
||||
width="30%"
|
||||
>
|
||||
<el-dialog title="" :visible.sync="mesDialog" custom-class="msgDialog" :before-close="handleClose" width="30%">
|
||||
|
||||
<span class="title">官方申明</span>
|
||||
<p>尊敬用户:</p>
|
||||
<p>您好~~ </p>
|
||||
<p>本平台公示的所有产品折扣活动均真实有效,价格体系严格遵循公开透明原则。 </p>
|
||||
<p> 特别说明:<span
|
||||
style="color: #7A82A0!important;">云服务产品页面所示价格属参考性标价,实际交易金额须以资源清单订单页面为准。</span>
|
||||
<p> 特别说明:<span style="color: #7A82A0!important;">云服务产品页面所示价格属参考性标价,实际交易金额须以资源清单订单页面为准。</span>
|
||||
</p>
|
||||
<p>请您知悉上述条款并放心进行购买决策,如有任何疑问,可随时联系平台官方客服,我们将为您详细说明。</p>
|
||||
<div style="margin-top: 85px" class="footerBox">
|
||||
@ -336,15 +318,15 @@
|
||||
</template>
|
||||
<script>
|
||||
import Vue from 'vue'
|
||||
import {reqHotProduct} from "@/api/newHome";
|
||||
import { reqHotProduct } from "@/api/newHome";
|
||||
import Talk from "@/views/homePage/dialog/talk/index.vue";
|
||||
import LogoG from "@/views/homePage/mainPage/logoG/index.vue";
|
||||
import {mapState} from "vuex";
|
||||
import { mapState } from "vuex";
|
||||
import IndexTwo from "@/views/homePage/mainPage/logoG/indexTwo.vue";
|
||||
|
||||
export default Vue.extend({
|
||||
name: "mainPage",
|
||||
components: {IndexTwo, LogoG, Talk},
|
||||
components: { IndexTwo, LogoG, Talk },
|
||||
data() {
|
||||
return {
|
||||
mesDialog: localStorage.getItem('showMsg') !== '1', // 初始状态
|
||||
@ -575,11 +557,15 @@ export default Vue.extend({
|
||||
font-size: 64px;
|
||||
|
||||
.leftText {
|
||||
background: linear-gradient(to right, #275AFF, #2EBDFA); /* 渐变方向颜色 */
|
||||
-webkit-background-clip: text; /* 关键属性:裁剪背景到文字 */
|
||||
background: linear-gradient(to right, #275AFF, #2EBDFA);
|
||||
/* 渐变方向颜色 */
|
||||
-webkit-background-clip: text;
|
||||
/* 关键属性:裁剪背景到文字 */
|
||||
background-clip: text;
|
||||
color: transparent; /* 文字颜色透明 */
|
||||
display: inline-block; /* 确保渐变生效 */
|
||||
color: transparent;
|
||||
/* 文字颜色透明 */
|
||||
display: inline-block;
|
||||
/* 确保渐变生效 */
|
||||
}
|
||||
}
|
||||
|
||||
@ -615,11 +601,15 @@ export default Vue.extend({
|
||||
}
|
||||
|
||||
.commonTextColor {
|
||||
background: linear-gradient(to right, #275AFF, #2EBDFA); /* 渐变方向颜色 */
|
||||
-webkit-background-clip: text; /* 关键属性:裁剪背景到文字 */
|
||||
background: linear-gradient(to right, #275AFF, #2EBDFA);
|
||||
/* 渐变方向颜色 */
|
||||
-webkit-background-clip: text;
|
||||
/* 关键属性:裁剪背景到文字 */
|
||||
background-clip: text;
|
||||
color: transparent; /* 文字颜色透明 */
|
||||
display: inline-block; /* 确保渐变生效 */
|
||||
color: transparent;
|
||||
/* 文字颜色透明 */
|
||||
display: inline-block;
|
||||
/* 确保渐变生效 */
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@ -650,11 +640,15 @@ export default Vue.extend({
|
||||
}
|
||||
|
||||
.price {
|
||||
background: linear-gradient(to right, #275AFF, #2EBDFA); /* 渐变方向颜色 */
|
||||
-webkit-background-clip: text; /* 关键属性:裁剪背景到文字 */
|
||||
background: linear-gradient(to right, #275AFF, #2EBDFA);
|
||||
/* 渐变方向颜色 */
|
||||
-webkit-background-clip: text;
|
||||
/* 关键属性:裁剪背景到文字 */
|
||||
background-clip: text;
|
||||
color: transparent; /* 文字颜色透明 */
|
||||
display: inline-block; /* 确保渐变生效 */
|
||||
color: transparent;
|
||||
/* 文字颜色透明 */
|
||||
display: inline-block;
|
||||
/* 确保渐变生效 */
|
||||
font-weight: bold;
|
||||
|
||||
.bigText {
|
||||
@ -737,10 +731,12 @@ export default Vue.extend({
|
||||
z-index: 10;
|
||||
padding-left: 50px;
|
||||
padding-top: 50px;
|
||||
color: #222F60;;
|
||||
color: #222F60;
|
||||
;
|
||||
|
||||
* {
|
||||
color: #222F60;;
|
||||
color: #222F60;
|
||||
;
|
||||
}
|
||||
|
||||
padding-bottom: 25px;
|
||||
@ -834,11 +830,15 @@ export default Vue.extend({
|
||||
}
|
||||
|
||||
.lookDetailStyle {
|
||||
background: linear-gradient(to right, #275AFF, #2EBDFA); /* 渐变方向颜色 */
|
||||
-webkit-background-clip: text; /* 关键属性:裁剪背景到文字 */
|
||||
background: linear-gradient(to right, #275AFF, #2EBDFA);
|
||||
/* 渐变方向颜色 */
|
||||
-webkit-background-clip: text;
|
||||
/* 关键属性:裁剪背景到文字 */
|
||||
background-clip: text;
|
||||
color: transparent; /* 文字颜色透明 */
|
||||
display: inline-block; /* 确保渐变生效 */
|
||||
color: transparent;
|
||||
/* 文字颜色透明 */
|
||||
display: inline-block;
|
||||
/* 确保渐变生效 */
|
||||
font-weight: bold;
|
||||
margin-left: 85px;
|
||||
border-radius: 12px;
|
||||
@ -926,11 +926,13 @@ export default Vue.extend({
|
||||
z-index: 10;
|
||||
padding-left: 50px;
|
||||
padding-top: 50px;
|
||||
color: #222F60;;
|
||||
color: #222F60;
|
||||
;
|
||||
|
||||
|
||||
* {
|
||||
color: #222F60;;
|
||||
color: #222F60;
|
||||
;
|
||||
}
|
||||
|
||||
width: 1400px;
|
||||
@ -1026,11 +1028,15 @@ export default Vue.extend({
|
||||
}
|
||||
|
||||
.lookDetailStyle {
|
||||
background: linear-gradient(to right, #275AFF, #2EBDFA); /* 渐变方向颜色 */
|
||||
-webkit-background-clip: text; /* 关键属性:裁剪背景到文字 */
|
||||
background: linear-gradient(to right, #275AFF, #2EBDFA);
|
||||
/* 渐变方向颜色 */
|
||||
-webkit-background-clip: text;
|
||||
/* 关键属性:裁剪背景到文字 */
|
||||
background-clip: text;
|
||||
color: transparent; /* 文字颜色透明 */
|
||||
display: inline-block; /* 确保渐变生效 */
|
||||
color: transparent;
|
||||
/* 文字颜色透明 */
|
||||
display: inline-block;
|
||||
/* 确保渐变生效 */
|
||||
font-weight: bold;
|
||||
margin-left: 85px;
|
||||
|
||||
@ -1097,10 +1103,12 @@ export default Vue.extend({
|
||||
z-index: 10;
|
||||
padding-left: 50px;
|
||||
padding-top: 50px;
|
||||
color: #222F60;;
|
||||
color: #222F60;
|
||||
;
|
||||
|
||||
* {
|
||||
color: #222F60;;
|
||||
color: #222F60;
|
||||
;
|
||||
}
|
||||
|
||||
padding-bottom: 25px;
|
||||
@ -1195,11 +1203,15 @@ export default Vue.extend({
|
||||
}
|
||||
|
||||
.lookDetailStyle {
|
||||
background: linear-gradient(to right, #275AFF, #2EBDFA); /* 渐变方向颜色 */
|
||||
-webkit-background-clip: text; /* 关键属性:裁剪背景到文字 */
|
||||
background: linear-gradient(to right, #275AFF, #2EBDFA);
|
||||
/* 渐变方向颜色 */
|
||||
-webkit-background-clip: text;
|
||||
/* 关键属性:裁剪背景到文字 */
|
||||
background-clip: text;
|
||||
color: transparent; /* 文字颜色透明 */
|
||||
display: inline-block; /* 确保渐变生效 */
|
||||
color: transparent;
|
||||
/* 文字颜色透明 */
|
||||
display: inline-block;
|
||||
/* 确保渐变生效 */
|
||||
font-weight: bold;
|
||||
margin-left: 85px;
|
||||
border-radius: 12px;
|
||||
@ -1300,21 +1312,30 @@ export default Vue.extend({
|
||||
|
||||
.numberStyle {
|
||||
position: relative;
|
||||
background: linear-gradient(to right, #275AFF, #2EBDFA); /* 渐变方向颜色 */
|
||||
-webkit-background-clip: text; /* 关键属性:裁剪背景到文字 */
|
||||
background: linear-gradient(to right, #275AFF, #2EBDFA);
|
||||
/* 渐变方向颜色 */
|
||||
-webkit-background-clip: text;
|
||||
/* 关键属性:裁剪背景到文字 */
|
||||
background-clip: text;
|
||||
color: transparent; /* 文字颜色透明 */
|
||||
display: inline-block; /* 确保渐变生效 */
|
||||
color: transparent;
|
||||
/* 文字颜色透明 */
|
||||
display: inline-block;
|
||||
|
||||
/* 确保渐变生效 */
|
||||
.mapTag {
|
||||
font-size: 24px;
|
||||
position: absolute;
|
||||
right: -20px;
|
||||
top: 0;
|
||||
background: linear-gradient(to right, #275AFF, #2EBDFA); /* 渐变方向颜色 */
|
||||
-webkit-background-clip: text; /* 关键属性:裁剪背景到文字 */
|
||||
background: linear-gradient(to right, #275AFF, #2EBDFA);
|
||||
/* 渐变方向颜色 */
|
||||
-webkit-background-clip: text;
|
||||
/* 关键属性:裁剪背景到文字 */
|
||||
background-clip: text;
|
||||
color: transparent; /* 文字颜色透明 */
|
||||
display: inline-block; /* 确保渐变生效 */
|
||||
color: transparent;
|
||||
/* 文字颜色透明 */
|
||||
display: inline-block;
|
||||
/* 确保渐变生效 */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BIN
f/web-kboss/src/views/homePage/ncmatch/mainPage/img/btnBg.png
Normal file
BIN
f/web-kboss/src/views/homePage/ncmatch/mainPage/img/btnBg.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 187 KiB |
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1753777468651" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6851" xmlns:xlink="http://www.w3.org/1999/xlink" width="14" height="14"><path d="M566.61333333 480.32426667c175.3088 16.384 309.6576 109.7728 309.6576 222.27626666 0 124.5184-163.29386667 225.00693333-364.81706666 225.00693334S147.18293333 827.11893333 147.18293333 703.14666667c0-102.67306667 111.4112-189.50826667 264.32853334-216.2688v103.76533333c0 20.20693333 8.192 39.86773333 22.9376 54.0672 14.7456 14.19946667 34.4064 22.39146667 54.61333333 22.39146667l6.5536-0.54613334c39.86773333-3.2768 70.4512-36.0448 70.99733333-76.45866666V480.32426667z" p-id="6852" fill="#ffffff"></path><path d="M492.88533333 61.44L801.45066667 243.3024c9.8304 5.46133333 12.56106667 18.0224 7.09973333 27.30666667-2.18453333 4.36906667-6.00746667 7.09973333-10.92266667 8.73813333l-277.43573333 97.21173333v207.53066667c0 15.83786667-13.1072 28.94506667-28.94506667 28.94506667s-28.94506667-12.56106667-28.94506666-28.94506667V78.91626667c0-7.09973333 3.82293333-14.19946667 10.37653333-17.47626667 6.00746667-3.82293333 13.65333333-3.82293333 20.20693333 0z" p-id="6853" fill="#ffffff"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1753777558445" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10925" xmlns:xlink="http://www.w3.org/1999/xlink" width="14" height="14"><path d="M781.1072 971.0592H249.2928c-90.3168 0-163.84-73.5232-163.84-163.84V402.688c0-90.3168 73.5232-163.84 163.84-163.84h531.8144c90.3168 0 163.84 73.5232 163.84 163.84v404.5312c0 90.3168-73.472 163.84-163.84 163.84zM249.2928 300.288c-56.4736 0-102.4 45.9264-102.4 102.4v404.5312c0 56.4736 45.9264 102.4 102.4 102.4h531.8144c56.4736 0 102.4-45.9264 102.4-102.4V402.688c0-56.4736-45.9264-102.4-102.4-102.4H249.2928z" fill="#ffffff" p-id="10926"></path><path d="M691.968 457.8816c-16.9472 0-30.72-13.7728-30.72-30.72V262.5024c0-81.664-66.4064-148.0704-148.0704-148.0704S365.1072 180.8384 365.1072 262.5024v164.6592c0 16.9472-13.7728 30.72-30.72 30.72s-30.72-13.7728-30.72-30.72V262.5024c0-115.5584 94.0032-209.5104 209.5104-209.5104s209.5104 94.0032 209.5104 209.5104v164.6592c0 16.9472-13.7216 30.72-30.72 30.72z" fill="#ffffff" p-id="10927"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1753777515332" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7923" xmlns:xlink="http://www.w3.org/1999/xlink" width="14" height="14"><path d="M316.034305 645.090181c-16.969487 0-30.789237-13.821797-30.789237-30.79026 0-16.991999 13.820774-30.841426 30.789237-30.841426l376.865253 0c16.993023 0 30.813796 13.847379 30.813796 30.841426 0 16.968463-13.820774 30.79026-30.813796 30.79026L316.034305 645.090181 316.034305 645.090181zM311.444776 811.624055c-16.995069 0-30.815843-13.82282-30.815843-30.81482 0-16.968463 13.81975-30.815843 30.815843-30.815843l376.838647 0c16.994046 0 30.81482 13.847379 30.81482 30.815843 0 16.991999-13.820774 30.81482-30.81482 30.81482L311.444776 811.624055 311.444776 811.624055zM144.125003 1024c-53.214992 0-83.21526-33.604352-83.21526-84.266196L60.909743 116.042923c0-48.669466 24.882714-90.86652 85.261872-90.86652l530.546402 0c12.982686 0 24.206308 6.936993 30.027897 18.554588 5.796006 11.631922 4.64274 24.785499-3.173273 35.168987-6.294356 8.419763-16.33913 13.45443-26.854625 13.45443l-442.508299 0c-19.617803 0-35.196617 0-47.888683 0l-25.255197 0c-7.945973 0-14.319124 0-19.984147 0l-13.034874-0.039909 0 864.495216 771.300674 0-0.024559-13.007245c-0.077771-19.433608-0.052189-33.910321-0.026606-52.241828l0-0.788969c0-11.120268 0.026606-23.813359 0.026606-40.1003L899.322931 361.549429c0-10.476609 4.982478-20.494777 13.323447-26.802436 6.033413-4.510734 12.955056-6.872524 20.062941-6.872524 16.231683 0 33.778314 12.863982 33.778314 33.662681l0 582.291926c0 25.308409-5.506411 44.662199-16.338107 57.485249-12.668531 15.030321-34.146705 22.686698-63.832817 22.686698L144.125003 1024 144.125003 1024zM824.397475 53.905724l7.867178-9.677407c6.531763-8.063653 15.448854-19.092847 20.928658-25.110911 9.31004-10.215666 22.107507-15.631002 37.004799-15.631002 9.335622 0 17.333784 2.085498 22.421662 3.843538 16.944927 5.820566 39.312354 25.387203 49.907667 43.612287 11.434423 19.709901 11.33107 39.969317-0.261966 55.599296-9.389858 12.745279-16.809851 22.212908-19.590174 25.675776l-7.107885 8.955976L824.397475 53.905724 824.397475 53.905724zM614.432439 472.129944c-6.242168 0-11.304464-1.952468-15.080463-5.810333-4.771677-4.889357-6.897084-12.285814-6.661723-23.248494 0.419556-18.712177 10.490935-77.614705 14.320147-90.099041 2.883677-9.388834 6.39771-17.873066 14.160511-28.691459 11.199063-15.552208 150.09139-199.605084 177.812755-236.347916l7.082302-9.360182L917.077294 165.785837l-6.738471 9.009188c-39.235606 52.267411-167.714769 223.508493-174.953637 232.766344-6.374174 8.157797-14.923898 16.194844-22.843264 21.4925-16.548908 11.106965-69.654406 36.911678-87.146802 41.475624C621.276311 471.606011 617.683483 472.129944 614.432439 472.129944L614.432439 472.129944 614.432439 472.129944z" fill="#ffffff" p-id="7924"></path></svg>
|
||||
|
After Width: | Height: | Size: 2.9 KiB |
@ -1,23 +1,95 @@
|
||||
<script lang="ts">
|
||||
import Vue from 'vue'
|
||||
|
||||
import { reqPublishProductSearchFirstPage } from '@/api/ncmatch'
|
||||
export default Vue.extend({
|
||||
name: "mainPage",
|
||||
components: {
|
||||
sendProduct: () => import('./sendProduct/index.vue'),
|
||||
productCard: () => import('./productCard/index.vue')
|
||||
},
|
||||
created() {
|
||||
this.init_product_list()
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
searchKeyword: '洗烘一体洗衣机',
|
||||
sendProductVisible: false,
|
||||
currentHotMenu: "",
|
||||
product: [],
|
||||
hotProductList: [
|
||||
// {
|
||||
// id: 1,
|
||||
// name: 'NVIDIA-4090',
|
||||
// image: 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjE1MCIgdmlld0JveD0iMCAwIDIwMCAxNTAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIyMDAiIGhlaWdodD0iMTUwIiBmaWxsPSIjMjIyMjIyIi8+Cjx0ZXh0IHg9IjEwMCIgeT0iNzUiIGZvbnQtZmFtaWx5PSJBcmlhbCIgZm9udC1zaXplPSIxNCIgZmlsbD0id2hpdGUiIHRleHQtYW5jaG9yPSJtaWRkbGUiPk5WSUQpQSBSVFggNDA5MDwvdGV4dD4KPC9zdmc+Cg==',
|
||||
// price: 6000,
|
||||
// cpu: 'AMD EPYC 7542 32 C * 2',
|
||||
// memory: '64G DDR4-3200 * 8',
|
||||
// gpu: 'NVIDIA-4090-24GB * 8',
|
||||
// sys_disk: '960G SATA SSD * 2 (Raid)',
|
||||
// data_disk: '3.84T U.2 NVMe SSD * 1',
|
||||
// net_card: 'Mellanox Connect4 25G SFP28 2-port * 1'
|
||||
// },
|
||||
// {
|
||||
// id: 2,
|
||||
// name: 'NVIDIA-4090',
|
||||
// image: 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjE1MCIgdmlld0JveD0iMCAwIDIwMCAxNTAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIyMDAiIGhlaWdodD0iMTUwIiBmaWxsPSIjMjIyMjIyIi8+Cjx0ZXh0IHg9IjEwMCIgeT0iNzUiIGZvbnQtZmFtaWx5PSJBcmlhbCIgZm9udC1zaXplPSIxNCIgZmlsbD0id2hpdGUiIHRleHQtYW5jaG9yPSJtaWRkbGUiPk5WSUQpQSBSVFggNDA5MDwvdGV4dD4KPC9zdmc+Cg==',
|
||||
// price: 6000,
|
||||
// cpu: 'AMD EPYC 7542 32 C * 2',
|
||||
// memory: '64G DDR4-3200 * 8',
|
||||
// gpu: 'NVIDIA-4090-24GB * 8',
|
||||
// sys_disk: '960G SATA SSD * 2 (Raid)',
|
||||
// data_disk: '3.84T U.2 NVMe SSD * 1',
|
||||
// net_card: 'Mellanox Connect4 25G SFP28 2-port * 1'
|
||||
// }
|
||||
],
|
||||
hotMenuList: [
|
||||
{
|
||||
id: "hot",
|
||||
name: "热门推荐",
|
||||
icon: require("../../newImg/niu.png"),
|
||||
activeIcon: require("../../newImg/niuActive.png")
|
||||
},
|
||||
{
|
||||
id: "hlzx",
|
||||
name: "互联网专线",
|
||||
icon: require("../../newImg/niu.png"),
|
||||
activeIcon: require("../../newImg/niuActive.png"),
|
||||
},
|
||||
{
|
||||
id: "SDWAN",
|
||||
name: "SDWAN",
|
||||
icon: require("../../newImg/niu.png"),
|
||||
activeIcon: require("../../newImg/niuActive.png"),
|
||||
},
|
||||
{
|
||||
id: "DCI",
|
||||
name: "DCI",
|
||||
icon: require("../../newImg/niu.png"),
|
||||
activeIcon: require("../../newImg/niuActive.png"),
|
||||
},
|
||||
{
|
||||
id: "AI",
|
||||
name: "AI专线",
|
||||
icon: require("../../newImg/niu.png"),
|
||||
activeIcon: require("../../newImg/niuActive.png"),
|
||||
}
|
||||
],
|
||||
searchKeyword: '',
|
||||
hotSearchKeywords: [
|
||||
'京东奢品 低至2折',
|
||||
'大牌空调低至5折',
|
||||
'夏日防晒',
|
||||
'饮用水',
|
||||
'哑铃',
|
||||
'家庭清洁',
|
||||
'户外用品',
|
||||
'补水喷雾',
|
||||
'坚果炒货',
|
||||
'四件套',
|
||||
'佛雷他定'
|
||||
'昆仑芯-P800',
|
||||
'天垓-150',
|
||||
'4090',
|
||||
'云服务器-GPU',
|
||||
'人脸识别',
|
||||
'SDWAN',
|
||||
'互联网专线',
|
||||
'DCI',
|
||||
'AI专线',
|
||||
'对象存储',
|
||||
'智慧医疗',
|
||||
'智慧客服',
|
||||
'A800',
|
||||
'A100',
|
||||
'910B'
|
||||
],
|
||||
topNavItems: [
|
||||
{ name: '早十好价', icon: '10', color: 'red' },
|
||||
@ -32,125 +104,280 @@ export default Vue.extend({
|
||||
{ name: '全部频道', icon: '📱', color: 'rainbow' }
|
||||
],
|
||||
categories: [
|
||||
{ name: '家用电器', icon: '🏠' },
|
||||
{ name: '手机/运营商/数码', icon: '📱' },
|
||||
{ name: '电脑/办公/文具用品', icon: '💻' },
|
||||
{ name: '家居/家具/家装/厨具', icon: '🪑' },
|
||||
{ name: '男装/女装/童装/内衣', icon: '👕' },
|
||||
{ name: '美妆/个护清洁/宠物', icon: '💄' },
|
||||
{ name: '女鞋/箱包/钟表/珠宝', icon: '👠' },
|
||||
{ name: '男鞋/运动/户外', icon: '👟' },
|
||||
{ name: '房产/汽车/汽车用品', icon: '🏠' },
|
||||
{ name: '母婴/玩具乐器', icon: '👶' },
|
||||
{ name: '食品/酒类/生鲜/特产', icon: '🍎' }
|
||||
{ name: '云', icon: '🏠', product_list: ['百度云'] },
|
||||
{ name: '国产算力', icon: '📱', product_list: ['昇腾910B', 'P800', '其他'] },
|
||||
{ name: 'NVIDIA', icon: '💻', product_list: ['3090', '4090', '5080', '5090'] },
|
||||
{ name: '网', icon: '🪑', product_list: ['AI专线', 'SDWAN', '互联网专线', 'DCI'] },
|
||||
{ name: '一体机', icon: '👕', product_list: ['昆仑芯', '天数智芯'] },
|
||||
{ name: '硬件', icon: '💄', product_list: ['机器人', 'AR眼镜'] },
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
init_product_list() {
|
||||
reqPublishProductSearchFirstPage({ url_link: window.location.href }).then(res => {
|
||||
if (res.status) {
|
||||
this.currentHotMenu = res.data[0].id
|
||||
this.hotProductList = res.data[0].product_list
|
||||
this.product = res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
sendProductSuccess() {
|
||||
this.sendProductVisible = false; // 关闭弹窗
|
||||
},
|
||||
clickNetMenu(menu) {
|
||||
this.currentHotMenu = menu.id;
|
||||
this.hotProductList = menu.product_list || [];
|
||||
},
|
||||
handleSearch() {
|
||||
console.log('搜索:', this.searchKeyword)
|
||||
console.log('搜索:1', this.searchKeyword)
|
||||
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="jd-homepage">
|
||||
<!-- 顶部Header -->
|
||||
<header class="header">
|
||||
<div class="header-content">
|
||||
<!-- 左侧Logo -->
|
||||
<div class="logo-section">
|
||||
<div class="logo">
|
||||
<span class="logo-text">京东</span>
|
||||
<span class="logo-mascot">🐕</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 中间搜索区域 -->
|
||||
<div class="search-section">
|
||||
<div class="search-bar">
|
||||
<input
|
||||
v-model="searchKeyword"
|
||||
type="text"
|
||||
class="search-input"
|
||||
placeholder="洗烘一体洗衣机"
|
||||
>
|
||||
|
||||
<button class="search-btn" @click="handleSearch">搜索</button>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- 热搜关键词 -->
|
||||
<div class="hot-search">
|
||||
<a
|
||||
v-for="keyword in hotSearchKeywords"
|
||||
:key="keyword"
|
||||
href="#"
|
||||
class="hot-keyword"
|
||||
>
|
||||
{{ keyword }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<!-- 主内容区域 -->
|
||||
<main class="main-content">
|
||||
<div class="content-wrapper">
|
||||
<!-- 左侧分类导航 -->
|
||||
<aside class="category-sidebar">
|
||||
<ul class="category-list">
|
||||
<li
|
||||
v-for="category in categories"
|
||||
:key="category.name"
|
||||
class="category-item"
|
||||
>
|
||||
<span class="category-icon">{{ category.icon }}</span>
|
||||
<span class="category-name">{{ category.name }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</aside>
|
||||
|
||||
<!-- 中间主内容 -->
|
||||
<section class="main-section">
|
||||
<!-- 顶部促销横幅 -->
|
||||
<div class="promo-banner">
|
||||
<div class="banner-content">
|
||||
<div class="banner-text">
|
||||
<h3>今日精选</h3>
|
||||
<p>冰箱天天特价</p>
|
||||
<p>超值乐购</p>
|
||||
</div>
|
||||
<div class="banner-image">
|
||||
<img src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjE1MCIgdmlld0JveD0iMCAwIDIwMCAxNTAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxMDAiIGhlaWdodD0iMTUwIiBmaWxsPSIjMzMzIi8+Cjx0ZXh0IHg9IjUwIiB5PSI3NSIgZm9udC1mYW1pbHk9IkFyaWFsIiBmb250LXNpemU9IjEyIiBmaWxsPSJ3aGl0ZSIgdGV4dC1hbmNob3I9Im1pZGRsZSI+5YyF5a2Q6KOFPC90ZXh0Pgo8L3N2Zz4K" alt="冰箱" class="fridge-img">
|
||||
<span class="flower-decoration">🌸</span>
|
||||
</div>
|
||||
<div class="jd-homepage">
|
||||
<!-- 顶部Header -->
|
||||
<header class="header">
|
||||
<div class="header-content">
|
||||
<!-- 左侧Logo -->
|
||||
<div class="logo-section">
|
||||
<div class="logo">
|
||||
<!-- <span class="logo-text">京东</span> -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 中间搜索区域 -->
|
||||
<div class="search-section">
|
||||
<div class="search-bar">
|
||||
<input v-model="searchKeyword" type="text" class="search-input" placeholder="4090">
|
||||
|
||||
</section>
|
||||
<button class="search-btn" @click="handleSearch">搜索</button>
|
||||
|
||||
<!-- 右侧用户信息栏 -->
|
||||
<aside class="user-sidebar">
|
||||
<!-- 用户问候卡片 -->
|
||||
<div class="user-card">
|
||||
<div class="user-greeting">
|
||||
<h4>Hi~下午好</h4>
|
||||
<p>登录后享更多优惠</p>
|
||||
</div>
|
||||
<button class="login-btn">立即登录</button>
|
||||
<a href="#" class="register-link">注册></a>
|
||||
</div>
|
||||
|
||||
</aside>
|
||||
<!-- 热搜关键词 -->
|
||||
<div class="hot-search">
|
||||
<a v-for="keyword in hotSearchKeywords" :key="keyword" href="#" class="hot-keyword">
|
||||
{{ keyword }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<!-- 主内容区域 -->
|
||||
<main class="main-content">
|
||||
<div class="content-wrapper">
|
||||
<!-- 左侧分类导航 -->
|
||||
<aside class="category-sidebar">
|
||||
<ul class="category-list">
|
||||
<li v-for="category in categories" :key="category.name" class="category-item">
|
||||
<span class="category-icon">{{ category.icon }}</span>
|
||||
<span class="category-name">{{ category.name }}</span>
|
||||
<span style="display: flex;border: 1px solid red;margin-left: 0px;padding-left: 0px;">|</span>
|
||||
<div class="menu-item">
|
||||
<span v-for="(product, index) in category.product_list" :key="product">
|
||||
{{ product }}{{ index < category.product_list.length - 1 ? ' / ' : '' }}
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</aside>
|
||||
|
||||
<!-- 中间主内容 -->
|
||||
<section class="main-section">
|
||||
<!-- 顶部促销横幅 -->
|
||||
<div id="banner" class="banner">
|
||||
<div class="centerBox">
|
||||
<span style="margin-top: 100px" class="title">
|
||||
<span class="leftText">
|
||||
Ncmatch
|
||||
</span>
|
||||
<span class="rightText" style="margin-left: 10px;"> 您身边的AI管家</span>
|
||||
</span>
|
||||
<!-- <span class="description">支持模型训练、推理和数据处理,灵活配置,助您高效释放AI潜能</span>-->
|
||||
<ul style="margin-top: 50px" class="tagUl">
|
||||
<li>全 球 领 先 的 AI 服 务 运 营 商</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 右侧用户信息栏 -->
|
||||
<aside class="user-sidebar">
|
||||
<span class="publish-goods"> <img src="./img/gc.svg" alt=""> 算力供需广场</span>
|
||||
<span class="publish-goods">发布需求</span>
|
||||
<span class="publish-goods" @click="sendProductVisible = true">发布商品</span>
|
||||
</aside>
|
||||
</div>
|
||||
</main>
|
||||
<div class="productList">
|
||||
<ul class="myTab">
|
||||
<li v-for="menu in product" :class="currentHotMenu === menu.id ? 'activeMenu' : ''" @click="clickNetMenu(menu)"
|
||||
:key="menu.name">
|
||||
<!-- <img :src="currentHotMenu === menu.id ? menu.activeIcon : menu.icon" alt="" /> -->
|
||||
<span class="tab-text">{{ menu.name }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<productCard :productList="hotProductList"></productCard>
|
||||
<el-dialog title="发布商品" width="60vw" top="5vh" :visible.sync="sendProductVisible">
|
||||
<sendProduct @success="sendProductSuccess"></sendProduct>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.menu-item {
|
||||
flex: 1;
|
||||
border: 1px solid red;
|
||||
font-size: 13px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
min-width: 0; /* 确保flex子项可以收缩 */
|
||||
}
|
||||
|
||||
.productList {
|
||||
width: 1400px;
|
||||
margin: 0 auto;
|
||||
border: 1px solid red;
|
||||
}
|
||||
|
||||
.publish-goods {
|
||||
margin-bottom: 25px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
border-radius: 10px;
|
||||
background: url('./img//btnBg.png');
|
||||
background-size: cover;
|
||||
background-position: top;
|
||||
color: #222F60 !important;
|
||||
font-size: 18px;
|
||||
font-weight: 900;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
// background: #2EBDFA;
|
||||
}
|
||||
}
|
||||
|
||||
.banner {
|
||||
border-radius: 10px;
|
||||
background: url("../../newImg/banner.png");
|
||||
width: 100%;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
|
||||
.centerBox {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
position: absolute;
|
||||
top: 35%;
|
||||
left: 50%;
|
||||
width: 100%;
|
||||
transform: translate(-50%, -50%);
|
||||
|
||||
.title {
|
||||
color: #222F60;
|
||||
font-size: 42px;
|
||||
display: flex;
|
||||
|
||||
.leftText {
|
||||
background: linear-gradient(to right, #275AFF, #2EBDFA);
|
||||
/* 渐变方向颜色 */
|
||||
-webkit-background-clip: text;
|
||||
/* 关键属性:裁剪背景到文字 */
|
||||
background-clip: text;
|
||||
color: transparent;
|
||||
/* 文字颜色透明 */
|
||||
display: inline-block;
|
||||
/* 确保渐变生效 */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.description {
|
||||
margin: 15px 0;
|
||||
color: #7A82A0;
|
||||
font-size: 24px;
|
||||
height: 75px;
|
||||
line-height: 1.6;
|
||||
border: 1px solid red;
|
||||
}
|
||||
|
||||
.tagUl {
|
||||
color: #222F60;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 24px;
|
||||
|
||||
li {
|
||||
padding: 0 30px;
|
||||
margin-top: 25px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
&:not(:last-child) {
|
||||
border-right: 2px solid #D2D7E6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.myTab {
|
||||
width: 100%;
|
||||
font-size: 18px;
|
||||
border-radius: 16px;
|
||||
background: #f7f8fc;
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.activeMenu {
|
||||
background: linear-gradient(90deg, #275AFF 0%, #2EBDFA 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
li {
|
||||
transition: all .2s ease-in-out;
|
||||
z-index: 2;
|
||||
padding: 10px 20px;
|
||||
margin-right: 45px;
|
||||
border-radius: 8px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer !important;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.jd-homepage {
|
||||
min-height: 100vh;
|
||||
background-color: #f8fbfe;
|
||||
@ -162,8 +389,13 @@ export default Vue.extend({
|
||||
padding: 10px 0;
|
||||
|
||||
.header-content {
|
||||
max-width: 1200px;
|
||||
|
||||
max-width: 1400px;
|
||||
margin: 0 auto;
|
||||
margin-top: 15px;
|
||||
margin-left: 200px;
|
||||
margin-right: 200px;
|
||||
border: 1px solid red;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
@ -268,17 +500,18 @@ export default Vue.extend({
|
||||
// 主内容区域
|
||||
.main-content {
|
||||
padding: 16px;
|
||||
max-width: 1200px;
|
||||
max-width: 1400px;
|
||||
margin: 20px auto;
|
||||
margin-top: 10px;
|
||||
height: 500px;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
background-color:white;
|
||||
border:1px solid red;
|
||||
background-color: white;
|
||||
border: 1px solid red;
|
||||
|
||||
.content-wrapper {
|
||||
box-sizing: border-box;
|
||||
display: grid;
|
||||
grid-template-columns: 200px 1fr 250px;
|
||||
grid-template-columns: 300px 1fr 250px;
|
||||
gap: 20px;
|
||||
}
|
||||
}
|
||||
@ -287,7 +520,7 @@ export default Vue.extend({
|
||||
.category-sidebar {
|
||||
background-color: #f8fbfe;
|
||||
height: 100%;
|
||||
border-radius: 4px;
|
||||
border-radius: 10px;
|
||||
padding: 15px;
|
||||
|
||||
.category-list {
|
||||
@ -295,11 +528,14 @@ export default Vue.extend({
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
||||
|
||||
.category-item {
|
||||
border: 1px solid red;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 4px 0;
|
||||
margin-bottom: 5px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
@ -334,6 +570,7 @@ export default Vue.extend({
|
||||
margin-bottom: 20px;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
|
||||
.banner-content {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
@ -373,7 +610,9 @@ export default Vue.extend({
|
||||
|
||||
}
|
||||
|
||||
.subsidy-section, .live-section, .seckill-section {
|
||||
.subsidy-section,
|
||||
.live-section,
|
||||
.seckill-section {
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
@ -391,7 +630,9 @@ export default Vue.extend({
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.official-tag, .live-tag, .seckill-tag {
|
||||
.official-tag,
|
||||
.live-tag,
|
||||
.seckill-tag {
|
||||
background: #e1251b;
|
||||
color: white;
|
||||
padding: 4px 8px;
|
||||
@ -401,257 +642,13 @@ export default Vue.extend({
|
||||
}
|
||||
}
|
||||
|
||||
.product-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 15px;
|
||||
|
||||
.product-card {
|
||||
text-align: center;
|
||||
|
||||
.product-img {
|
||||
margin-bottom: 10px;
|
||||
|
||||
img {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
object-fit: cover;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.product-info {
|
||||
.subsidy-amount {
|
||||
color: #e1251b;
|
||||
font-size: 12px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.product-price {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.morning-deal-section {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 15px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.deal-card {
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
|
||||
&.left-card {
|
||||
h4 {
|
||||
margin: 0 0 15px 0;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.deal-list {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
||||
li {
|
||||
padding: 8px 0;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
color: #666;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.right-card {
|
||||
text-align: center;
|
||||
|
||||
h4 {
|
||||
margin: 0 0 15px 0;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.deal-product {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
|
||||
img {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
object-fit: cover;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.deal-price {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #e1251b;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.live-cards {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 15px;
|
||||
|
||||
.live-card {
|
||||
background: #f8f9fa;
|
||||
border-radius: 8px;
|
||||
padding: 15px;
|
||||
text-align: center;
|
||||
|
||||
.live-preview {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
|
||||
.live-icon {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.live-text {
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.live-name {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.seckill-products {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 15px;
|
||||
|
||||
.seckill-product {
|
||||
text-align: center;
|
||||
|
||||
img {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
object-fit: cover;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.seckill-price {
|
||||
color: #e1251b;
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.free-shipping-section, .one-yuan-section {
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
h3 {
|
||||
margin: 0 0 15px 0;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.shipping-products {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.shipping-product, .one-yuan-product {
|
||||
text-align: center;
|
||||
|
||||
img {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
object-fit: cover;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.shipping-price, .one-yuan-price {
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 右侧用户信息栏
|
||||
.user-sidebar {
|
||||
height: 100%;
|
||||
.user-card {
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.user-avatar {
|
||||
font-size: 40px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.user-greeting {
|
||||
margin-bottom: 15px;
|
||||
|
||||
h4 {
|
||||
margin: 0 0 5px 0;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
color: #666;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.login-btn {
|
||||
background: #e1251b;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 10px 20px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
margin-bottom: 10px;
|
||||
width: 100%;
|
||||
|
||||
&:hover {
|
||||
background: #c1191f;
|
||||
}
|
||||
}
|
||||
|
||||
.register-link {
|
||||
color: #666;
|
||||
text-decoration: none;
|
||||
font-size: 12px;
|
||||
|
||||
&:hover {
|
||||
color: #e1251b;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 响应式设计
|
||||
@media (max-width: 1200px) {
|
||||
@ -666,7 +663,8 @@ export default Vue.extend({
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.category-sidebar, .user-sidebar {
|
||||
.category-sidebar,
|
||||
.user-sidebar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,182 @@
|
||||
<template>
|
||||
<!-- 产品列表 -->
|
||||
<ul class="productListContent" style="padding: 16px;">
|
||||
<li v-if="type === 'homePage'" class="product-item" v-for="item in productList" :key="item.id">
|
||||
<div class="product-image">
|
||||
<img :src="item.img" style="min-width: 278px;min-height: 185px;" :alt="item.name">
|
||||
</div>
|
||||
<div class="product-info">
|
||||
<h3 class="product-name">{{ item.name }}</h3>
|
||||
<div class="product-specs">
|
||||
<div class="spec-item">
|
||||
<span class="spec-label">CPU:</span>
|
||||
<span class="spec-value">{{ item.cpu }}</span>
|
||||
</div>
|
||||
<div class="spec-item">
|
||||
<span class="spec-label">内存:</span>
|
||||
<span class="spec-value">{{ item.memory }}</span>
|
||||
</div>
|
||||
<div class="spec-item">
|
||||
<span class="spec-label">GPU:</span>
|
||||
<span class="spec-value">{{ item.gpu }}</span>
|
||||
</div>
|
||||
<div class="spec-item">
|
||||
<span class="spec-label">系统盘:</span>
|
||||
<span class="spec-value">{{ item.sys_disk }}</span>
|
||||
</div>
|
||||
<div class="spec-item">
|
||||
<span class="spec-label">数据盘:</span>
|
||||
<span class="spec-value">{{ item.data_disk }}</span>
|
||||
</div>
|
||||
<div class="spec-item">
|
||||
<span class="spec-label">网卡:</span>
|
||||
<span class="spec-value">{{ item.net_card }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="product-price">
|
||||
<span class="price">¥{{ item.price }}</span>
|
||||
<span class="price-unit">/台/月 (可短租)</span>
|
||||
</div>
|
||||
<button class="consult-btn">立即咨询</button>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'productCard',
|
||||
props: {
|
||||
productList: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'homePage'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.productListContent {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 20px;
|
||||
padding: 16px;
|
||||
max-width: 1400px;
|
||||
margin: 0 auto;
|
||||
background-color: white;
|
||||
border: 1px solid red;
|
||||
|
||||
.product-item {
|
||||
|
||||
|
||||
width: 100%;
|
||||
background: #F7F9FD;
|
||||
border-radius: 12px;
|
||||
// box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
padding: 24px;
|
||||
|
||||
margin-bottom: 20px;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
// &:hover {
|
||||
// transform: translateY(-2px);
|
||||
// box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
|
||||
// }
|
||||
|
||||
.product-image {
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
max-width: 300px;
|
||||
height: 200px;
|
||||
object-fit: cover;
|
||||
border-radius: 8px;
|
||||
background: #1a1a1a;
|
||||
}
|
||||
}
|
||||
|
||||
.product-info {
|
||||
.product-name {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin: 0 0 16px 0;
|
||||
text-align: start;
|
||||
}
|
||||
|
||||
.product-specs {
|
||||
margin-bottom: 20px;
|
||||
|
||||
.spec-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 8px 0;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.spec-label {
|
||||
color: #222F60 !important;
|
||||
font-size: 14px;
|
||||
font-weight: 900;
|
||||
min-width: 80px;
|
||||
}
|
||||
|
||||
.spec-value {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
text-align: right;
|
||||
flex: 1;
|
||||
margin-left: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.product-price {
|
||||
text-align: start;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.price {
|
||||
font-size: 28px;
|
||||
font-weight: bold;
|
||||
color: #e1251b;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.price-unit {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
|
||||
.consult-btn {
|
||||
width: 100%;
|
||||
background: linear-gradient(90deg, #275AFF 0%, #2EBDFA 100%);
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 12px 24px;
|
||||
border-radius: 8px;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 12px rgba(39, 90, 255, 0.3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,19 @@
|
||||
export const buildCaTree = (data,parentid=null) => {
|
||||
const tree = [];
|
||||
for (const item of data) {
|
||||
if (item.parentid === parentid) {
|
||||
const children = buildCaTree(data, item.id);
|
||||
let i = {
|
||||
label:item.product_category,
|
||||
value:item.id,
|
||||
cart_flag:item.cart_flag
|
||||
}
|
||||
if (children.length > 0) {
|
||||
i.children = children;
|
||||
}
|
||||
|
||||
tree.push(i);
|
||||
}
|
||||
}
|
||||
return tree;
|
||||
};
|
||||
@ -0,0 +1,904 @@
|
||||
<template>
|
||||
<div class="form-container">
|
||||
<el-form :model="form" :rules="rules" ref="form" label-width="120px" class="two-column-form">
|
||||
<!-- 商品图片 - 单独一行 -->
|
||||
<el-form-item label="商品图片" prop="img" class="full-width">
|
||||
<div class="upload-area" @click="!selectedImage && triggerFileInput()">
|
||||
<input ref="fileInput" type="file" accept="image/*" @change="handleFileChange"
|
||||
style="display: none;">
|
||||
<div v-if="!selectedImage" class="upload-placeholder">
|
||||
<i class="el-icon-plus" style="font-size: 40px;"></i>
|
||||
</div>
|
||||
<div v-else class="image-preview">
|
||||
<img :src="selectedImage" alt="预览图" @click="previewImage">
|
||||
<div class="preview-overlay">
|
||||
<i class="el-icon-zoom-in"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 图片操作按钮 -->
|
||||
<div v-if="selectedImage" class="image-actions">
|
||||
<el-button size="mini" type="primary" @click="previewImage">预览图片</el-button>
|
||||
<el-button size="mini" type="primary" @click="openCropper">裁剪图片</el-button>
|
||||
<el-button size="mini" type="danger" @click="removeImage">删除</el-button>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品名称" prop="product_name" required>
|
||||
<el-input v-model="form.product_name" placeholder="请输入商品名称"></el-input>
|
||||
</el-form-item>
|
||||
<!-- 表单项直接排列 -->
|
||||
<div class="form-row">
|
||||
<el-form-item label="所属类别" prop="product_category" required class="form-item-half">
|
||||
<el-cascader v-model="form.product_category" style="width: 100%;" :options="typeList"
|
||||
@change="handleChange"></el-cascader>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="企业名称" prop="company_name" required class="form-item-half">
|
||||
<el-input v-model="form.company_name" placeholder="请输入企业名称"></el-input>
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<el-form-item label="公司类别" prop="company_type" required class="full-width">
|
||||
|
||||
<el-checkbox-group v-model="form.company_type">
|
||||
<el-checkbox v-for="item in company_category_list" :key="item.value"
|
||||
:label="item.label"></el-checkbox>
|
||||
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
|
||||
<div class="form-row">
|
||||
<el-form-item label="联系人" prop="contact_person" required class="form-item-half">
|
||||
<el-input v-model="form.contact_person" placeholder="请输入联系人姓名"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="职务" prop="job_title" class="form-item-half">
|
||||
<el-input v-model="form.job_title" placeholder="请输入职务"></el-input>
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<el-form-item label="手机号码" prop="phone_number" required class="form-item-half">
|
||||
<el-input v-model="form.phone_number" placeholder="请输入手机号码"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="邮箱" prop="email" class="form-item-half">
|
||||
<el-input v-model="form.email" placeholder="请输入邮箱地址"></el-input>
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
||||
<div class="form-row" v-if="current_product_category.cart_flag=='1'">
|
||||
<el-form-item label="CPU" class="form-item-half">
|
||||
<el-input v-model="form.cpu" placeholder="请输入CPU规格"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="内存" class="form-item-half">
|
||||
<el-input v-model="form.memory" placeholder="请输入内存规格"></el-input>
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
||||
<div class="form-row" v-if="current_product_category.cart_flag=='1'">
|
||||
<el-form-item label="GPU" class="form-item-half">
|
||||
<el-input v-model="form.gpu" placeholder="请输入GPU规格"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="系统盘" class="form-item-half">
|
||||
<el-input v-model="form.sys_disk" placeholder="请输入系统盘规格"></el-input>
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
||||
<div class="form-row" v-if="current_product_category.cart_flag=='1'">
|
||||
<el-form-item label="数据盘" class="form-item-half">
|
||||
<el-input v-model="form.data_disk" placeholder="请输入数据盘规格"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="网卡" prop="net_card" required class="form-item-half">
|
||||
<el-input v-model="form.net_card" placeholder="请输入网卡规格"></el-input>
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<el-form-item label="价格" prop="price" required class="form-item-half">
|
||||
<el-input v-model="form.price" placeholder="请输入价格: 示例: xx元/台/月"></el-input>
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
||||
<el-form-item label="商品概述" prop="requirement_summary" required class="full-width">
|
||||
<el-input type="textarea" v-model="form.requirement_summary" :rows="6" placeholder="请输入商品概述"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="相关参数" prop="related_parameters" class="full-width">
|
||||
<el-input type="textarea" v-model="form.related_parameters" :rows="6" placeholder="请输入相关参数"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="应用场景" prop="application_scenario" class="full-width">
|
||||
<el-input type="textarea" v-model="form.application_scenario" :rows="6"
|
||||
placeholder="请输入应用场景"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 提交按钮 -->
|
||||
<div class="form-actions">
|
||||
<el-button type="primary" @click="submitForm" size="large">提交</el-button>
|
||||
<el-button @click="resetForm" size="large">重置</el-button>
|
||||
<!-- <el-button type="info" @click="getBinaryData" size="large">获取二进制数据</el-button> -->
|
||||
</div>
|
||||
</el-form>
|
||||
|
||||
<!-- 图片裁剪弹窗 -->
|
||||
<el-dialog title="图片裁剪" :visible.sync="showCropper" width="60%" top="5vh" :before-close="closeCropper"
|
||||
custom-class="cropper-dialog" :append-to-body="true" :modal-append-to-body="true" :z-index="9999"
|
||||
:destroy-on-close="true">
|
||||
<div class="cropper-container">
|
||||
<vue-cropper ref="cropper" :img="cropperImage" :outputSize="1" :info="true" :full="true" :canMove="true"
|
||||
:canMoveBox="true" :original="false" :autoCrop="true" :autoCropWidth="300" :autoCropHeight="200"
|
||||
:fixed="false" :centerBox="true" :infoTrue="true" :high="true" mode="cover" :maxImgSize="2000"
|
||||
:enlargeImg="1" :limitMinSize="[100, 100]" @realTime="realTime" />
|
||||
</div>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="closeCropper">取消</el-button>
|
||||
<el-button type="primary" @click="cropImage">确认裁剪</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 图片预览弹窗 -->
|
||||
<el-dialog title="图片预览" :visible.sync="showPreview" width="50%" center top="5vh" :append-to-body="true"
|
||||
:modal-append-to-body="true" :z-index="9998" :destroy-on-close="true" custom-class="preview-dialog">
|
||||
<div class="preview-container">
|
||||
<img :src="selectedImage" alt="预览图" class="preview-image">
|
||||
</div>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="showPreview = false">关闭</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { VueCropper } from 'vue-cropper'
|
||||
import { buildCaTree } from './buildCaTree'
|
||||
import { reqGetProductCategorySearch, reqPublishProductAdd, reqCompanyCategorySearch } from '@/api/ncmatch'
|
||||
export default {
|
||||
name: 'sendProduct',
|
||||
components: {
|
||||
VueCropper
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
company_category_list: [],
|
||||
typeList: [
|
||||
|
||||
],
|
||||
current_product_category: {},//当前选中的商品类别
|
||||
selectedImage: null,
|
||||
showCropper: false,
|
||||
showPreview: false,
|
||||
cropperImage: '',
|
||||
inputVisible: false,
|
||||
inputValue: '',
|
||||
form: {
|
||||
url_link: window.location.href,
|
||||
img: null, // 商品图片二进制数据
|
||||
product_name: "",//商品名称
|
||||
product_category: "",//商品类别
|
||||
company_name: "",//公司名称
|
||||
company_type: [],//公司类型
|
||||
contact_person: "",//联系人
|
||||
job_title: "",//职务
|
||||
phone_number: "",//手机号码
|
||||
email: "",//邮箱
|
||||
cpu: "",//CPU
|
||||
memory: "",//内存
|
||||
gpu: "",//GPU
|
||||
sys_disk: "",//系统盘
|
||||
data_disk: "",//数据盘
|
||||
net_card: "",//网卡
|
||||
priority: "",//优先级
|
||||
price: "",//价格
|
||||
label: "",//标签
|
||||
requirement_summary: "",//需求概述
|
||||
related_parameters: "",//相关参数
|
||||
application_scenario: "",//应用场景
|
||||
},
|
||||
rules: {
|
||||
product_category: [
|
||||
{ required: true, message: '请选择所属类别', trigger: 'change' }
|
||||
],
|
||||
company_name: [
|
||||
{ required: true, message: '请输入企业名称', trigger: 'blur' }
|
||||
],
|
||||
company_type: [
|
||||
{ required: true, message: '请选择公司类别', trigger: 'change' }
|
||||
],
|
||||
contact_person: [
|
||||
{ required: true, message: '请输入联系人', trigger: 'blur' }
|
||||
],
|
||||
phone_number: [
|
||||
{ required: true, message: '请输入手机号码', trigger: 'blur' },
|
||||
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号码', trigger: 'blur' }
|
||||
],
|
||||
email: [
|
||||
{ type: 'email', message: '请输入正确的邮箱地址', trigger: 'blur' }
|
||||
],
|
||||
cpu: [
|
||||
{ required: true, message: '请输入CPU规格', trigger: 'blur' }
|
||||
],
|
||||
memory: [
|
||||
{ required: true, message: '请输入内存规格', trigger: 'blur' }
|
||||
],
|
||||
gpu: [
|
||||
{ required: true, message: '请输入GPU规格', trigger: 'blur' }
|
||||
],
|
||||
sys_disk: [
|
||||
{ required: true, message: '请输入系统盘规格', trigger: 'blur' }
|
||||
],
|
||||
data_disk: [
|
||||
{ required: true, message: '请输入数据盘规格', trigger: 'blur' }
|
||||
],
|
||||
net_card: [
|
||||
{ required: true, message: '请输入网卡规格', trigger: 'blur' }
|
||||
],
|
||||
price: [
|
||||
{ required: true, message: '请输入价格', trigger: 'blur' }
|
||||
],
|
||||
img: [
|
||||
{
|
||||
required: true,
|
||||
validator: (rule, value, callback) => {
|
||||
if (!value) {
|
||||
callback(new Error('请上传商品图片'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
},
|
||||
trigger: 'change'
|
||||
}
|
||||
],
|
||||
requirement_summary: [
|
||||
{ required: true, message: '请输入商品概述', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.init_product_category()
|
||||
this.init_company_category()
|
||||
},
|
||||
methods: {
|
||||
init_company_category() {
|
||||
reqCompanyCategorySearch({ userid: '9KVhsVCJsW_29q3hRhMAr' }).then(res => {
|
||||
if (res.status) {
|
||||
this.company_category_list = []
|
||||
for (let item of res.data) {
|
||||
this.company_category_list.push({
|
||||
label: item.company_category,
|
||||
value: item.company_category
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
},
|
||||
// 将base64字符串转换为Blob对象
|
||||
base64ToBlob(base64, mimeType = 'image/jpeg') {
|
||||
const byteString = atob(base64.split(',')[1]);
|
||||
const ab = new ArrayBuffer(byteString.length);
|
||||
const ia = new Uint8Array(ab);
|
||||
for (let i = 0; i < byteString.length; i++) {
|
||||
ia[i] = byteString.charCodeAt(i);
|
||||
}
|
||||
return new Blob([ab], { type: mimeType });
|
||||
},
|
||||
|
||||
init_product_category() {
|
||||
reqGetProductCategorySearch({ userid: '9KVhsVCJsW_29q3hRhMAr' }).then(res => {
|
||||
if (res.status) {
|
||||
this.typeList = buildCaTree(res.data)
|
||||
console.log("2@@", this.typeList);
|
||||
|
||||
}
|
||||
})
|
||||
},
|
||||
// 触发文件选择
|
||||
triggerFileInput() {
|
||||
this.$refs.fileInput.click()
|
||||
},
|
||||
|
||||
// 处理文件选择
|
||||
handleFileChange(event) {
|
||||
const file = event.target.files[0]
|
||||
if (file) {
|
||||
// 检查文件大小
|
||||
if (file.size > 5 * 1024 * 1024) {
|
||||
this.$message.error('图片大小不能超过5MB')
|
||||
return
|
||||
}
|
||||
|
||||
// 检查文件类型
|
||||
if (!file.type.startsWith('image/')) {
|
||||
this.$message.error('请选择图片文件')
|
||||
return
|
||||
}
|
||||
|
||||
console.log('选择的文件:', file)
|
||||
console.log('文件类型:', file.type)
|
||||
console.log('文件大小:', file.size)
|
||||
|
||||
// 保存二进制数据到 img 字段
|
||||
this.form.img = file
|
||||
|
||||
// 创建URL用于预览
|
||||
const imageUrl = URL.createObjectURL(file)
|
||||
this.selectedImage = imageUrl
|
||||
|
||||
console.log('保存到 form.img:', this.form.img)
|
||||
this.$refs.form.validateField('img')
|
||||
}
|
||||
},
|
||||
|
||||
// 打开裁剪器
|
||||
openCropper() {
|
||||
if (this.form.img) {
|
||||
// 将File对象转换为base64用于裁剪器
|
||||
const reader = new FileReader()
|
||||
reader.onload = (e) => {
|
||||
this.cropperImage = e.target.result
|
||||
this.showCropper = true
|
||||
// 确保DOM更新后再初始化裁剪器
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.cropper) {
|
||||
this.$refs.cropper.refresh()
|
||||
}
|
||||
// 强制设置dialog层级
|
||||
setTimeout(() => {
|
||||
const dialogWrapper = document.querySelector('.cropper-dialog')
|
||||
if (dialogWrapper) {
|
||||
dialogWrapper.style.zIndex = '9999'
|
||||
}
|
||||
}, 100)
|
||||
})
|
||||
}
|
||||
reader.readAsDataURL(this.form.img)
|
||||
}
|
||||
},
|
||||
|
||||
// 关闭裁剪器
|
||||
closeCropper() {
|
||||
this.showCropper = false
|
||||
this.cropperImage = ''
|
||||
},
|
||||
|
||||
// 实时预览
|
||||
realTime(data) {
|
||||
// 可以在这里处理实时预览数据
|
||||
console.log('裁剪实时数据:', data)
|
||||
},
|
||||
|
||||
// 执行裁剪
|
||||
cropImage() {
|
||||
this.$refs.cropper.getCropData((data) => {
|
||||
// data 是裁剪后的图片base64数据
|
||||
// 将base64转换为Blob二进制数据
|
||||
const blob = this.base64ToBlob(data)
|
||||
this.form.img = blob
|
||||
|
||||
// 创建URL用于预览
|
||||
this.selectedImage = URL.createObjectURL(blob)
|
||||
|
||||
this.$message.success('图片裁剪成功!')
|
||||
this.closeCropper()
|
||||
})
|
||||
},
|
||||
|
||||
// 删除图片
|
||||
removeImage() {
|
||||
// 清理 URL
|
||||
if (this.selectedImage) {
|
||||
URL.revokeObjectURL(this.selectedImage)
|
||||
}
|
||||
this.selectedImage = null
|
||||
this.form.img = null
|
||||
this.$refs.fileInput.value = ''
|
||||
this.$refs.form.validateField('img')
|
||||
},
|
||||
|
||||
// 预览图片
|
||||
previewImage() {
|
||||
if (this.selectedImage) {
|
||||
this.showPreview = true
|
||||
}
|
||||
},
|
||||
|
||||
// 标签管理
|
||||
removeTag(tag) {
|
||||
this.form.companyTags.splice(this.form.companyTags.indexOf(tag), 1)
|
||||
},
|
||||
|
||||
showInput() {
|
||||
this.inputVisible = true
|
||||
this.$nextTick(_ => {
|
||||
this.$refs.saveTagInput.$refs.input.focus()
|
||||
})
|
||||
},
|
||||
|
||||
handleInputConfirm() {
|
||||
let inputValue = this.inputValue
|
||||
if (inputValue) {
|
||||
this.form.companyTags.push(inputValue)
|
||||
}
|
||||
this.inputVisible = false
|
||||
this.inputValue = ''
|
||||
},
|
||||
|
||||
// 提交表单
|
||||
submitForm() {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
console.log('表单数据:', this.form)
|
||||
let formdata = new FormData();
|
||||
for (let key in this.form) {
|
||||
formdata.append(key, this.form[key]);
|
||||
}
|
||||
|
||||
reqPublishProductAdd(formdata).then(res => {
|
||||
if (res.status) {
|
||||
this.$emit('success');
|
||||
this.$message.success('添加产品成功!')
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.$message.error('请完善表单信息')
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 重置表单
|
||||
resetForm() {
|
||||
// 清理 URL
|
||||
if (this.selectedImage) {
|
||||
URL.revokeObjectURL(this.selectedImage)
|
||||
}
|
||||
this.$refs.form.resetFields()
|
||||
this.selectedImage = null
|
||||
this.form.img = null
|
||||
this.$refs.fileInput.value = ''
|
||||
},
|
||||
|
||||
// 处理级联选择器变化
|
||||
handleChange(value) {
|
||||
console.log('选中的id数组:', value)
|
||||
// 递归查找节点对象
|
||||
function findNodeByValue(options, value) {
|
||||
for (let item of options) {
|
||||
if (item.value === value) return item;
|
||||
if (item.children) {
|
||||
const found = findNodeByValue(item.children, value);
|
||||
if (found) return found;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
const currentId = value[value.length - 1];
|
||||
const currentNode = findNodeByValue(this.typeList, currentId);
|
||||
console.log('当前节点对象:', currentNode);
|
||||
this.current_product_category = currentNode
|
||||
},
|
||||
|
||||
// 获取二进制数据的示例方法
|
||||
getBinaryData() {
|
||||
console.log('form.img:', this.form.img)
|
||||
console.log('form.img 类型:', typeof this.form.img)
|
||||
console.log('form.img 构造函数:', this.form.img?.constructor?.name)
|
||||
|
||||
if (this.form.img) {
|
||||
console.log('二进制数据 (Blob/File):', this.form.img)
|
||||
console.log('文件大小:', this.form.img.size, '字节')
|
||||
console.log('文件类型:', this.form.img.type)
|
||||
|
||||
// 如果需要将Blob转换为File对象
|
||||
const file = new File([this.form.img], 'cropped-image.jpg', {
|
||||
type: this.form.img.type
|
||||
})
|
||||
console.log('File对象:', file)
|
||||
|
||||
// 如果需要将Blob转换为ArrayBuffer
|
||||
const reader = new FileReader()
|
||||
reader.onload = (e) => {
|
||||
const arrayBuffer = e.target.result
|
||||
console.log('ArrayBuffer:', arrayBuffer)
|
||||
}
|
||||
reader.readAsArrayBuffer(this.form.img)
|
||||
|
||||
return this.form.img
|
||||
} else {
|
||||
console.log('没有二进制数据')
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.form-container {
|
||||
padding: 20px;
|
||||
max-width: 1000px;
|
||||
margin: 0 auto;
|
||||
|
||||
.form-row {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.form-item-half {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
/* 防止flex项目溢出 */
|
||||
}
|
||||
}
|
||||
|
||||
.full-width {
|
||||
width: 100%;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
// 确保表单项在两列布局中正确显示
|
||||
.el-form-item {
|
||||
margin-bottom: 18px;
|
||||
|
||||
&.form-item-half {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
&.full-width {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
text-align: center;
|
||||
padding: 20px 0;
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.tags-container {
|
||||
.el-tag {
|
||||
margin-right: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.tag-input {
|
||||
width: 90px;
|
||||
margin-right: 8px;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
.button-new-tag {
|
||||
margin-left: 8px;
|
||||
height: 32px;
|
||||
line-height: 30px;
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.upload-area {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
overflow: hidden;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border: 2px dashed #ddd;
|
||||
border-radius: 8px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
background: #fafafa;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
&:hover {
|
||||
border-color: #409EFF;
|
||||
background: #f0f9ff;
|
||||
}
|
||||
|
||||
.upload-placeholder {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 1px solid #ddd;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
i {
|
||||
color: #999;
|
||||
display: block;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 5px 0;
|
||||
color: #666;
|
||||
|
||||
&.upload-tip {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.image-preview {
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
max-height: 300px;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
}
|
||||
|
||||
.preview-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
border-radius: 8px;
|
||||
|
||||
i {
|
||||
color: white;
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover .preview-overlay {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.image-actions {
|
||||
margin-top: 15px;
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.image-actions {
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 裁剪弹窗样式
|
||||
.cropper-dialog {
|
||||
z-index: 9999 !important;
|
||||
|
||||
.el-dialog {
|
||||
z-index: 9999 !important;
|
||||
}
|
||||
|
||||
.el-dialog__wrapper {
|
||||
z-index: 9999 !important;
|
||||
}
|
||||
|
||||
.el-dialog__mask {
|
||||
z-index: 9998 !important;
|
||||
}
|
||||
|
||||
.cropper-container {
|
||||
height: 350px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background: #f5f5f5;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
text-align: center;
|
||||
padding: 20px 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 预览弹窗样式
|
||||
.preview-dialog {
|
||||
z-index: 9998 !important;
|
||||
|
||||
.el-dialog {
|
||||
z-index: 9998 !important;
|
||||
}
|
||||
|
||||
.el-dialog__wrapper {
|
||||
z-index: 9998 !important;
|
||||
}
|
||||
|
||||
.el-dialog__mask {
|
||||
z-index: 9997 !important;
|
||||
}
|
||||
|
||||
.preview-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
background: #f5f5f5;
|
||||
border-radius: 8px;
|
||||
min-height: 300px;
|
||||
|
||||
.preview-image {
|
||||
max-width: 100%;
|
||||
max-height: 500px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
text-align: center;
|
||||
padding: 20px 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 全局样式确保裁剪器正常工作
|
||||
:global(.vue-cropper) {
|
||||
.cropper-container {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
.cropper-wrap-box {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
.cropper-canvas {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
.cropper-view-box {
|
||||
border: 1px solid #fff;
|
||||
box-shadow: 0 0 0 1px #39f;
|
||||
}
|
||||
|
||||
.cropper-face {
|
||||
background-color: rgba(39, 90, 255, 0.1);
|
||||
}
|
||||
|
||||
.cropper-line {
|
||||
background-color: #39f;
|
||||
}
|
||||
|
||||
.cropper-point {
|
||||
background-color: #39f;
|
||||
border: 1px solid #fff;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
// 强制设置dialog层级
|
||||
:global(.el-dialog__wrapper) {
|
||||
&.cropper-dialog {
|
||||
z-index: 9999 !important;
|
||||
}
|
||||
}
|
||||
|
||||
:global(.el-dialog) {
|
||||
&.cropper-dialog {
|
||||
z-index: 9999 !important;
|
||||
}
|
||||
}
|
||||
|
||||
// 确保裁剪dialog在最顶部
|
||||
:global(.cropper-dialog) {
|
||||
z-index: 9999 !important;
|
||||
|
||||
.el-dialog {
|
||||
z-index: 9999 !important;
|
||||
}
|
||||
|
||||
.el-dialog__wrapper {
|
||||
z-index: 9999 !important;
|
||||
}
|
||||
|
||||
.el-dialog__mask {
|
||||
z-index: 9998 !important;
|
||||
}
|
||||
}
|
||||
|
||||
// 全局样式覆盖
|
||||
:deep(.vue-cropper) {
|
||||
.cropper-view-box {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.cropper-face {
|
||||
background-color: rgba(39, 90, 255, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
// 确保裁剪器正常显示
|
||||
:deep(.vue-cropper) {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
position: relative;
|
||||
|
||||
.cropper-container {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.cropper-wrap-box {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.cropper-canvas {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.cropper-view-box {
|
||||
border: 1px solid #fff;
|
||||
box-shadow: 0 0 0 1px #39f;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.cropper-face {
|
||||
background-color: rgba(39, 90, 255, 0.1);
|
||||
}
|
||||
|
||||
.cropper-line {
|
||||
background-color: #39f;
|
||||
}
|
||||
|
||||
.cropper-point {
|
||||
background-color: #39f;
|
||||
border: 1px solid #fff;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
.cropper-center {
|
||||
background-color: #39f;
|
||||
border: 1px solid #fff;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
.cropper-dashed {
|
||||
border: 0 dashed #fff;
|
||||
}
|
||||
|
||||
.cropper-modal {
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.cropper-bg {
|
||||
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwgAADsIBFShKgAAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xOdTWsmQAAAGiSURBVDhPY2AYBYMRMDIyMjAyMjL8//+f4f///wz//v1j+Pv3L8OfP38Yfv/+zfDnzx+G37//MPz69Yvh58+fDD9+/GD4/v07w7dv3xi+fv3K8OXLF4bPnz8zfPr0ieHjx48MHz58YHj//j3Du3fvGN6+fcvw5s0bhtevXzO8evWK4eXLlwwvXrxgeP78OcOzZ88Ynj59yvDkyROGx48fMzx69Ijh4cOHDA8ePGC4f/8+w7179xju3r3LcOfOHYbbt28z3Lp1i+HmzZsMN27cYLh+/TrDtWvXGK5evcpw5coVhsuXLzNcunSJ4eLFiwwXLlxgOH/+PMO5c+cYzp49y3DmzBmG06dPM5w6dYrh5MmTDCdOnGA4fvw4w7FjxxiOHj3KcOTIEYbDhw8zHDp0iOHgwYMMBw4cYNi/fz/Dvn37GPbu3cuwZ88eht27dzPs2rWLYefOnQw7duxg2L59O8O2bdsYtm7dyrBlyxaGzZs3M2zatIlh48aNDBs2bGBYv349w7p16xjWrl3LsGbNGoZVq1YxrFy5kmHFihUMy5cvZ1i2bBnD0qVLGZYsWcKwePFihkWLFjEsXLiQYcGCBQzz59nmDdvHsPcuXMZ5syZwzB79myGWbNmMcycOZNhxowZDNOnT2eYNm0aw9SpUxmmTJnCMHnyZIZJkyYxTJw4kWHChAkM48ePZxg3bhzD2LFjGcaMGcMwevRohlGjRjGMHDmSYcSIEQzDhw9nGDZsGMPQoUMZhgwZwjB48GCGQYMG0Q8AABKxLhX5TqgFAAAAAElFTkSuQmCC');
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,564 @@
|
||||
<template>
|
||||
<div class="form-container">
|
||||
<el-form :model="form" :rules="rules" ref="form" label-width="100px">
|
||||
<el-form-item label="商品图片" prop="image">
|
||||
<div class="upload-area" @click="!selectedImage && triggerFileInput()">
|
||||
<input
|
||||
ref="fileInput"
|
||||
type="file"
|
||||
accept="image/*"
|
||||
@change="handleFileChange"
|
||||
style="display: none;"
|
||||
>
|
||||
<div v-if="!selectedImage" class="upload-placeholder">
|
||||
<i class="el-icon-plus" style="font-size: 40px;"></i>
|
||||
|
||||
<!-- <p class="upload-tip">支持 JPG、PNG 格式,最大 5MB</p> -->
|
||||
</div>
|
||||
<div v-else class="image-preview">
|
||||
<img :src="selectedImage" alt="预览图" @click="previewImage">
|
||||
<div class="preview-overlay">
|
||||
<i class="el-icon-zoom-in"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 图片操作按钮 -->
|
||||
<div v-if="selectedImage" class="image-actions">
|
||||
<el-button size="mini" type="primary" @click="previewImage">预览图片</el-button>
|
||||
<el-button size="mini" type="primary" @click="openCropper">裁剪图片</el-button>
|
||||
<el-button size="mini" type="danger" @click="removeImage">删除</el-button>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="submitForm">提交</el-button>
|
||||
<el-button @click="resetForm">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<!-- 图片裁剪弹窗 -->
|
||||
<el-dialog
|
||||
title="图片裁剪"
|
||||
:visible.sync="showCropper"
|
||||
width="60%"
|
||||
top="5vh"
|
||||
:before-close="closeCropper"
|
||||
custom-class="cropper-dialog"
|
||||
:append-to-body="true"
|
||||
:modal-append-to-body="true"
|
||||
:z-index="9999"
|
||||
:destroy-on-close="true"
|
||||
>
|
||||
<div class="cropper-container">
|
||||
<vue-cropper
|
||||
ref="cropper"
|
||||
:img="cropperImage"
|
||||
:outputSize="1"
|
||||
:info="true"
|
||||
:full="true"
|
||||
:canMove="true"
|
||||
:canMoveBox="true"
|
||||
:original="false"
|
||||
:autoCrop="true"
|
||||
:autoCropWidth="300"
|
||||
:autoCropHeight="200"
|
||||
:fixed="false"
|
||||
:centerBox="true"
|
||||
:infoTrue="true"
|
||||
:high="true"
|
||||
mode="cover"
|
||||
:maxImgSize="2000"
|
||||
:enlargeImg="1"
|
||||
:limitMinSize="[100, 100]"
|
||||
@realTime="realTime"
|
||||
/>
|
||||
</div>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="closeCropper">取消</el-button>
|
||||
<el-button type="primary" @click="cropImage">确认裁剪</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 图片预览弹窗 -->
|
||||
<el-dialog
|
||||
title="图片预览"
|
||||
:visible.sync="showPreview"
|
||||
width="50%"
|
||||
center
|
||||
top="5vh"
|
||||
:append-to-body="true"
|
||||
:modal-append-to-body="true"
|
||||
:z-index="9998"
|
||||
:destroy-on-close="true"
|
||||
custom-class="preview-dialog"
|
||||
>
|
||||
<div class="preview-container">
|
||||
<img :src="selectedImage" alt="预览图" class="preview-image">
|
||||
</div>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="showPreview = false">关闭</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { VueCropper } from 'vue-cropper'
|
||||
|
||||
export default {
|
||||
name: 'sendProduct',
|
||||
components: {
|
||||
VueCropper
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selectedImage: null,
|
||||
showCropper: false,
|
||||
showPreview: false,
|
||||
cropperImage: '',
|
||||
form: {
|
||||
image: ''
|
||||
},
|
||||
rules: {
|
||||
image: [
|
||||
{ required: true, message: '请上传商品图片', trigger: 'change' }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 触发文件选择
|
||||
triggerFileInput() {
|
||||
this.$refs.fileInput.click()
|
||||
},
|
||||
|
||||
// 处理文件选择
|
||||
handleFileChange(event) {
|
||||
const file = event.target.files[0]
|
||||
if (file) {
|
||||
// 检查文件大小
|
||||
if (file.size > 5 * 1024 * 1024) {
|
||||
this.$message.error('图片大小不能超过5MB')
|
||||
return
|
||||
}
|
||||
|
||||
// 检查文件类型
|
||||
if (!file.type.startsWith('image/')) {
|
||||
this.$message.error('请选择图片文件')
|
||||
return
|
||||
}
|
||||
|
||||
const reader = new FileReader()
|
||||
reader.onload = (e) => {
|
||||
this.selectedImage = e.target.result
|
||||
this.form.image = e.target.result
|
||||
this.$refs.form.validateField('image')
|
||||
}
|
||||
reader.readAsDataURL(file)
|
||||
}
|
||||
},
|
||||
|
||||
// 打开裁剪器
|
||||
openCropper() {
|
||||
if (this.selectedImage) {
|
||||
this.cropperImage = this.selectedImage
|
||||
this.showCropper = true
|
||||
// 确保DOM更新后再初始化裁剪器
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.cropper) {
|
||||
this.$refs.cropper.refresh()
|
||||
}
|
||||
// 强制设置dialog层级
|
||||
setTimeout(() => {
|
||||
const dialogWrapper = document.querySelector('.cropper-dialog')
|
||||
if (dialogWrapper) {
|
||||
dialogWrapper.style.zIndex = '9999'
|
||||
}
|
||||
}, 100)
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
// 关闭裁剪器
|
||||
closeCropper() {
|
||||
this.showCropper = false
|
||||
this.cropperImage = ''
|
||||
},
|
||||
|
||||
// 实时预览
|
||||
realTime(data) {
|
||||
// 可以在这里处理实时预览数据
|
||||
console.log('裁剪实时数据:', data)
|
||||
},
|
||||
|
||||
// 执行裁剪
|
||||
cropImage() {
|
||||
this.$refs.cropper.getCropData((data) => {
|
||||
// data 是裁剪后的图片base64数据
|
||||
this.selectedImage = data
|
||||
this.form.image = data
|
||||
this.$message.success('图片裁剪成功!')
|
||||
this.closeCropper()
|
||||
})
|
||||
},
|
||||
|
||||
// 删除图片
|
||||
removeImage() {
|
||||
this.selectedImage = null
|
||||
this.form.image = ''
|
||||
this.$refs.fileInput.value = ''
|
||||
this.$refs.form.validateField('image')
|
||||
},
|
||||
|
||||
// 预览图片
|
||||
previewImage() {
|
||||
if (this.selectedImage) {
|
||||
this.showPreview = true
|
||||
}
|
||||
},
|
||||
|
||||
// 提交表单
|
||||
submitForm() {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
console.log('表单数据:', this.form)
|
||||
this.$message.success('提交成功!')
|
||||
} else {
|
||||
this.$message.error('请完善表单信息')
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 重置表单
|
||||
resetForm() {
|
||||
this.$refs.form.resetFields()
|
||||
this.selectedImage = null
|
||||
this.$refs.fileInput.value = ''
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.form-container {
|
||||
padding: 20px;
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
|
||||
.upload-area {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
overflow: hidden;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border: 2px dashed #ddd;
|
||||
border-radius: 8px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
background: #fafafa;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
&:hover {
|
||||
border-color: #409EFF;
|
||||
background: #f0f9ff;
|
||||
}
|
||||
|
||||
.upload-placeholder {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 1px solid #ddd;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
i {
|
||||
color: #999;
|
||||
display: block;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 5px 0;
|
||||
color: #666;
|
||||
|
||||
&.upload-tip {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.image-preview {
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
max-height: 300px;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
}
|
||||
|
||||
.preview-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
border-radius: 8px;
|
||||
|
||||
i {
|
||||
color: white;
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover .preview-overlay {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.image-actions {
|
||||
margin-top: 15px;
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.image-actions {
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 裁剪弹窗样式
|
||||
.cropper-dialog {
|
||||
z-index: 9999 !important;
|
||||
|
||||
.el-dialog {
|
||||
z-index: 9999 !important;
|
||||
}
|
||||
|
||||
.el-dialog__wrapper {
|
||||
z-index: 9999 !important;
|
||||
}
|
||||
|
||||
.el-dialog__mask {
|
||||
z-index: 9998 !important;
|
||||
}
|
||||
|
||||
.cropper-container {
|
||||
height: 350px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background: #f5f5f5;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
text-align: center;
|
||||
padding: 20px 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 预览弹窗样式
|
||||
.preview-dialog {
|
||||
z-index: 9998 !important;
|
||||
|
||||
.el-dialog {
|
||||
z-index: 9998 !important;
|
||||
}
|
||||
|
||||
.el-dialog__wrapper {
|
||||
z-index: 9998 !important;
|
||||
}
|
||||
|
||||
.el-dialog__mask {
|
||||
z-index: 9997 !important;
|
||||
}
|
||||
|
||||
.preview-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
background: #f5f5f5;
|
||||
border-radius: 8px;
|
||||
min-height: 300px;
|
||||
|
||||
.preview-image {
|
||||
max-width: 100%;
|
||||
max-height: 500px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
text-align: center;
|
||||
padding: 20px 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 全局样式确保裁剪器正常工作
|
||||
:global(.vue-cropper) {
|
||||
.cropper-container {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
.cropper-wrap-box {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
.cropper-canvas {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
.cropper-view-box {
|
||||
border: 1px solid #fff;
|
||||
box-shadow: 0 0 0 1px #39f;
|
||||
}
|
||||
|
||||
.cropper-face {
|
||||
background-color: rgba(39, 90, 255, 0.1);
|
||||
}
|
||||
|
||||
.cropper-line {
|
||||
background-color: #39f;
|
||||
}
|
||||
|
||||
.cropper-point {
|
||||
background-color: #39f;
|
||||
border: 1px solid #fff;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
// 强制设置dialog层级
|
||||
:global(.el-dialog__wrapper) {
|
||||
&.cropper-dialog {
|
||||
z-index: 9999 !important;
|
||||
}
|
||||
}
|
||||
|
||||
:global(.el-dialog) {
|
||||
&.cropper-dialog {
|
||||
z-index: 9999 !important;
|
||||
}
|
||||
}
|
||||
|
||||
// 确保裁剪dialog在最顶部
|
||||
:global(.cropper-dialog) {
|
||||
z-index: 9999 !important;
|
||||
|
||||
.el-dialog {
|
||||
z-index: 9999 !important;
|
||||
}
|
||||
|
||||
.el-dialog__wrapper {
|
||||
z-index: 9999 !important;
|
||||
}
|
||||
|
||||
.el-dialog__mask {
|
||||
z-index: 9998 !important;
|
||||
}
|
||||
}
|
||||
|
||||
// 全局样式覆盖
|
||||
:deep(.vue-cropper) {
|
||||
.cropper-view-box {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.cropper-face {
|
||||
background-color: rgba(39, 90, 255, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
// 确保裁剪器正常显示
|
||||
:deep(.vue-cropper) {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
position: relative;
|
||||
|
||||
.cropper-container {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.cropper-wrap-box {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.cropper-canvas {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.cropper-view-box {
|
||||
border: 1px solid #fff;
|
||||
box-shadow: 0 0 0 1px #39f;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.cropper-face {
|
||||
background-color: rgba(39, 90, 255, 0.1);
|
||||
}
|
||||
|
||||
.cropper-line {
|
||||
background-color: #39f;
|
||||
}
|
||||
|
||||
.cropper-point {
|
||||
background-color: #39f;
|
||||
border: 1px solid #fff;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
.cropper-center {
|
||||
background-color: #39f;
|
||||
border: 1px solid #fff;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
.cropper-dashed {
|
||||
border: 0 dashed #fff;
|
||||
}
|
||||
|
||||
.cropper-modal {
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.cropper-bg {
|
||||
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwgAADsIBFShKgAAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xOdTWsmQAAAGiSURBVDhPY2AYBYMRMDIyMjAyMjL8//+f4f///wz//v1j+Pv3L8OfP38Yfv/+zfDnzx+G37//MPz69Yvh58+fDD9+/GD4/v07w7dv3xi+fv3K8OXLF4bPnz8zfPr0ieHjx48MHz58YHj//j3Du3fvGN6+fcvw5s0bhtevXzO8evWK4eXLlwwvXrxgeP78OcOzZ88Ynj59yvDkyROGx48fMzx69Ijh4cOHDA8ePGC4f/8+w7179xju3r3LcOfOHYbbt28z3Lp1i+HmzZsMN27cYLh+/TrDtWvXGK5evcpw5coVhsuXLzNcunSJ4eLFiwwXLlxgOH/+PMO5c+cYzp49y3DmzBmG06dPM5w6dYrh5MmTDCdOnGA4fvw4w7FjxxiOHj3KcOTIEYbDhw8zHDp0iOHgwYMMBw4cYNi/fz/Dvn37GPbu3cuwZ88eht27dzPs2rWLYefOnQw7duxg2L59O8O2bdsYtm7dyrBlyxaGzZs3M2zatIlh48aNDBs2bGBYv349w7p16xjWrl3LsGbNGoZVq1YxrFy5kmHFihUMy5cvZ1i2bBnD0qVLGZYsWcKwePFihkWLFjEsXLiQYcGCBQzz59nmDdvHsPcuXMZ5syZwzB79myGWbNmMcycOZNhxowZDNOnT2eYNm0aw9SpUxmmTJnCMHnyZIZJkyYxTJw4kWHChAkM48ePZxg3bhzD2LFjGcaMGcMwevRohlGjRjGMHDmSYcSIEQzDhw9nGDZsGMPQoUMZhgwZwjB48GCGQYMG0Q8AABKxLhX5TqgFAAAAAElFTkSuQmCC');
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,226 @@
|
||||
<template>
|
||||
<div class="main-box">
|
||||
<div style="width: 1400px;border: 1px solid red;">
|
||||
<div class="category-filter">
|
||||
<!-- 所属类别 -->
|
||||
<div class="category-section">
|
||||
<div class="category-title">所属类别</div>
|
||||
<div class="category-tags">
|
||||
<span v-for="category in categories" :key="category.id"
|
||||
:class="['category-tag', { active: selectedCategory === category.id }]"
|
||||
@click="selectCategory(category.id)">
|
||||
{{ category.name }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 公司类别 -->
|
||||
<div class="category-section">
|
||||
<div class="category-title">公司类别</div>
|
||||
<div class="category-tags">
|
||||
<span v-for="company in companies" :key="company.id"
|
||||
:class="['category-tag', { active: selectedCompany === company.id }]"
|
||||
@click="selectCompany(company.id)">
|
||||
{{ company.name }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 产品 -->
|
||||
<div class="product-card-container">
|
||||
<productCard v-if="productList.length > 0" :productList="productList"></productCard>
|
||||
<div v-else class="no-data">暂无数据</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'supplyAndDemandSquare',
|
||||
components: {
|
||||
productCard: () => import('@/views/homePage/ncmatch/mainPage/productCard/index.vue')
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selectedCategory: 'category2', // 默认选中项
|
||||
selectedCompany: 'company1', // 默认选中项
|
||||
categories: [
|
||||
{ id: 'category1', name: '云' },
|
||||
{ id: 'category2', name: '国产算力' },
|
||||
{ id: 'category3', name: 'NVIDIA' },
|
||||
{ id: 'category4', name: '网络服务' },
|
||||
{ id: 'category5', name: '一体机' },
|
||||
{ id: 'category6', name: '硬件' },
|
||||
{ id: 'category7', name: 'AI应用' },
|
||||
{ id: 'category8', name: '其他' }
|
||||
],
|
||||
companies: [
|
||||
{ id: 'company1', name: '龙头企业' },
|
||||
{ id: 'company2', name: '骨干企业' },
|
||||
{ id: 'company3', name: '科技型企业' },
|
||||
{ id: 'company4', name: '专精特新企业' },
|
||||
{ id: 'company5', name: '高新技术企业' },
|
||||
{ id: 'company6', name: '科技小巨人领军企业' },
|
||||
{ id: 'company7', name: '其他' }
|
||||
],
|
||||
productList: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
selectCategory(categoryId) {
|
||||
this.selectedCategory = categoryId
|
||||
},
|
||||
selectCompany(companyId) {
|
||||
this.selectedCompany = companyId
|
||||
},
|
||||
getProductList() {
|
||||
this.productList = [
|
||||
{
|
||||
id: 1,
|
||||
name: 'NVIDIA-4090',
|
||||
image: 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjE1MCIgdmlld0JveD0iMCAwIDIwMCAxNTAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIyMDAiIGhlaWdodD0iMTUwIiBmaWxsPSIjMjIyMjIyIi8+Cjx0ZXh0IHg9IjEwMCIgeT0iNzUiIGZvbnQtZmFtaWx5PSJBcmlhbCIgZm9udC1zaXplPSIxNCIgZmlsbD0id2hpdGUiIHRleHQtYW5jaG9yPSJtaWRkbGUiPk5WSUQpQSBSVFggNDA5MDwvdGV4dD4KPC9zdmc+Cg==',
|
||||
price: 6000,
|
||||
cpu: 'AMD EPYC 7542 32 C * 2',
|
||||
memory: '64G DDR4-3200 * 8',
|
||||
gpu: 'NVIDIA-4090-24GB * 8',
|
||||
sys_disk: '960G SATA SSD * 2 (Raid)',
|
||||
data_disk: '3.84T U.2 NVMe SSD * 1',
|
||||
net_card: 'Mellanox Connect4 25G SFP28 2-port * 1'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: 'NVIDIA-A100',
|
||||
image: 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjE1MCIgdmlld0JveD0iMCAwIDIwMCAxNTAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIyMDAiIGhlaWdodD0iMTUwIiBmaWxsPSIjMjIyMjIyIi8+Cjx0ZXh0IHg9IjEwMCIgeT0iNzUiIGZvbnQtZmFtaWx5PSJBcmlhbCIgZm9udC1zaXplPSIxNCIgZmlsbD0id2hpdGUiIHRleHQtYW5jaG9yPSJtaWRkbGUiPk5WSUQpQSBSVFggNDA5MDwvdGV4dD4KPC9zdmc+Cg==',
|
||||
price: 8000,
|
||||
cpu: 'AMD EPYC 7542 32 C * 2',
|
||||
memory: '128G DDR4-3200 * 8',
|
||||
gpu: 'NVIDIA-A100-80GB * 8',
|
||||
sys_disk: '1.92T SATA SSD * 2 (Raid)',
|
||||
data_disk: '7.68T U.2 NVMe SSD * 1',
|
||||
net_card: 'Mellanox Connect4 25G SFP28 2-port * 1'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '昇腾910B',
|
||||
image: 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjE1MCIgdmlld0JveD0iMCAwIDIwMCAxNTAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIyMDAiIGhlaWdodD0iMTUwIiBmaWxsPSIjMjIyMjIyIi8+Cjx0ZXh0IHg9IjEwMCIgeT0iNzUiIGZvbnQtZmFtaWx5PSJBcmlhbCIgZm9udC1zaXplPSIxNCIgZmlsbD0id2hpdGUiIHRleHQtYW5jaG9yPSJtaWRkbGUiPk5WSUQpQSBSVFggNDA5MDwvdGV4dD4KPC9zdmc+Cg==',
|
||||
price: 5000,
|
||||
cpu: 'Kunpeng 920 64 C * 2',
|
||||
memory: '64G DDR4-3200 * 8',
|
||||
gpu: '昇腾910B-32GB * 8',
|
||||
sys_disk: '960G SATA SSD * 2 (Raid)',
|
||||
data_disk: '3.84T U.2 NVMe SSD * 1',
|
||||
net_card: 'Mellanox Connect4 25G SFP28 2-port * 1'
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: '昆仑芯P800',
|
||||
image: 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjE1MCIgdmlld0JveD0iMCAwIDIwMCAxNTAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIyMDAiIGhlaWdodD0iMTUwIiBmaWxsPSIjMjIyMjIyIi8+Cjx0ZXh0IHg9IjEwMCIgeT0iNzUiIGZvbnQtZmFtaWx5PSJBcmlhbCIgZm9udC1zaXplPSIxNCIgZmlsbD0id2hpdGUiIHRleHQtYW5jaG9yPSJtaWRkbGUiPk5WSUQpQSBSVFggNDA5MDwvdGV4dD4KPC9zdmc+Cg==',
|
||||
price: 4000,
|
||||
cpu: 'Kunpeng 920 64 C * 2',
|
||||
memory: '64G DDR4-3200 * 8',
|
||||
gpu: '昆仑芯P800-16GB * 8',
|
||||
sys_disk: '960G SATA SSD * 2 (Raid)',
|
||||
data_disk: '3.84T U.2 NVMe SSD * 1',
|
||||
net_card: 'Mellanox Connect4 25G SFP28 2-port * 1'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getProductList()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.product-list{
|
||||
width: 100%;
|
||||
border: 1px solid red;
|
||||
// display: grid;
|
||||
// grid-template-columns: repeat(4, 1fr);
|
||||
// gap: 20px;
|
||||
.no-data{
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 产品卡片容器样式 */
|
||||
.product-card-container {
|
||||
margin-top: 20px;
|
||||
width: 100%;
|
||||
}
|
||||
.main-box {
|
||||
width: 100%;
|
||||
border: 1px solid red;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
|
||||
}
|
||||
|
||||
.category-filter {
|
||||
// padding: 20px;
|
||||
bottom: 1rem;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
margin: 20px;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
|
||||
.category-section {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
border: 1px solid red;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.category-title {
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
// margin-bottom: 12px;
|
||||
font-weight: 500;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
border: 1px solid red;
|
||||
height: 100%;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.category-tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
|
||||
.category-tag {
|
||||
padding: 3px 6px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #e8e8e8;
|
||||
border-radius: 2px;
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
border-color: #1890ff;
|
||||
color: #1890ff;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: #e6f7ff;
|
||||
border-color: #1890ff;
|
||||
color: #1890ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -1,6 +1,6 @@
|
||||
export function getHomePath() {
|
||||
// let homePath= "/homePage/index"
|
||||
let homePath= "/ncmatchHome/index"
|
||||
let homePath= "/homePage/index"
|
||||
// let homePath= "/ncmatchHome/index"
|
||||
|
||||
// 业主机构信息
|
||||
let url_link = window.location.href || '';
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user