style: 修改碳需求市场样式

This commit is contained in:
zheng020 2026-04-30 01:50:15 +08:00
parent baf775acbd
commit d966ffff1d
2 changed files with 258 additions and 252 deletions

View File

@ -884,6 +884,11 @@ export default {
color: #00b96b; color: #00b96b;
font-size: 14px; font-size: 14px;
font-weight: 400; font-weight: 400;
&:hover {
background: rgba(0, 154, 41, 0.1);
cursor: pointer;
}
} }
.price-value { .price-value {

View File

@ -16,13 +16,77 @@
{{ tab.label }} {{ tab.label }}
</button> </button>
</div> </div>
<div class="nav-right">
<span class="list-count"> {{ page.total }} 条需求</span>
<button class="publish-btn" @click="handlePublish">免费发布需求</button> <button class="publish-btn" @click="handlePublish">免费发布需求</button>
</div> </div>
</div> </div>
</div>
<main class="xqsc-main"> <main class="xqsc-main">
<div class="content-area"> <div class="content-area">
<!-- 左侧筛选栏 --> <!-- 左侧需求卡片列表 -->
<div class="demand-list">
<!-- 加载状态 -->
<div v-if="loading" class="loading-state">
<div class="loading-spinner"></div>
<p>加载中...</p>
</div>
<div class="demand-grid" v-else>
<div
v-for="card in cardList"
:key="card.gxUuid"
:data-gx-uuid="card.gxUuid"
class="demand-card"
>
<!-- 卡片头部 -->
<div class="card-header">
<div class="card-title-box">
<div class="card-title-text">
<div class="card-title-row">
<div :class="['demand-title', { urgent: card.urgent }]">
{{ card.bt1 }}
</div>
</div>
<div class="card-title-sub">
<div class="card-company">
<img src="../../assets/fwsc/city.svg" />
<span class="company-name">{{ card.qymc }}</span>
</div>
</div>
</div>
</div>
</div>
<!-- 卡片内容 -->
<div class="card-content">
<p class="card-desc">{{ card.fwnr }}</p>
<div class="card-tags">
<span v-for="(tag, i) in card.fwlxbqList" :key="i" class="tag">{{ tag }}</span>
</div>
</div>
<!-- 卡片底部 -->
<div class="card-footer">
<div class="card-budget">
<span class="budget-label">预算</span>
<span class="budget-value">{{ card.ysfwDm1 }}</span>
</div>
<div class="card-actions">
<span @click="handleContact(card)">立即咨询</span>
</div>
</div>
</div>
</div>
<!-- 空状态 -->
<div v-if="!loading && cardList.length === 0" class="empty-state">
<p>暂无需求信息</p>
</div>
</div>
<!-- 右侧筛选栏 -->
<aside class="filter-sidebar"> <aside class="filter-sidebar">
<div class="filter-toggle" @click="filterCollapsed = !filterCollapsed"> <div class="filter-toggle" @click="filterCollapsed = !filterCollapsed">
<span class="toggle-text">筛选</span> <span class="toggle-text">筛选</span>
@ -32,13 +96,12 @@
<!-- 内容搜索 --> <!-- 内容搜索 -->
<div class="filter-section"> <div class="filter-section">
<div class="filter-title">内容搜索</div> <div class="filter-title">内容搜索</div>
<t-input v-model="filter.nr" placeholder="请输入关键词" @enter="onSearch" /> <t-input v-model="filter.nr" placeholder="请输入关键词" @enter="onSearch">
<div class="filter-buttons"> <template #suffix-icon>
<t-button theme="primary" @click="onSearch">查询</t-button> <SearchIcon />
<t-button theme="default" @click="onReset">重置</t-button> </template>
</t-input>
</div> </div>
</div>
<!-- 服务地区 --> <!-- 服务地区 -->
<div class="filter-section"> <div class="filter-section">
@ -63,78 +126,19 @@
</div> </div>
</div> </div>
</aside> </aside>
<!-- 右侧需求卡片列表 -->
<div class="demand-list">
<div class="list-header">
<div class="list-title-box">
<span class="list-icon">📋</span>
<span class="list-title">碳需求市场</span>
</div>
<div class="list-right">
<span class="list-count"><span class="count-dot"></span> {{ page.total }} 条需求</span>
</div>
</div>
<!-- 加载状态 -->
<div v-if="loading" class="loading-state">
<div class="loading-spinner"></div>
<p>加载中...</p>
</div>
<div class="demand-grid" v-else>
<div
v-for="card in cardList"
:key="card.gxUuid"
:data-gx-uuid="card.gxUuid"
class="demand-card"
>
<!-- 卡片头部 -->
<div class="card-header">
<div :class="['demand-title', { urgent: card.urgent }]">
{{ card.bt1 }}
</div>
<div class="demand-company">{{ card.qymc }}</div>
</div>
<!-- 卡片内容 -->
<div class="card-content">
<div class="card-tags">
<span v-for="(tag, i) in card.fwlxbqList" :key="i" class="tag">{{ tag }}</span>
</div>
<p class="card-desc">{{ card.fwnr }}</p>
</div>
<!-- 卡片底部 -->
<div class="card-footer">
<div class="card-budget">
<span class="budget-label">预算</span>
<span class="budget-value">{{ card.ysfwDm1 }}</span>
</div>
<div class="card-actions">
<t-button theme="primary" size="small" @click="handleContact(card)">联系客户</t-button>
</div>
</div>
</div>
</div>
<!-- 空状态 -->
<div v-if="!loading && cardList.length === 0" class="empty-state">
<div class="empty-illustration">📋</div>
<p class="empty-text">暂无需求信息</p>
<p class="empty-hint">敬请期待更多优质需求上线</p>
</div>
</div>
</div> </div>
<!-- 分页 --> <!-- 分页 -->
<div class="pagination-box" v-if="page.total > 0"> <div class="pagination-box" v-if="page.total > 0">
<div class="pagination-total"> {{ page.total }} 条数据</div>
<t-pagination <t-pagination
v-model="page.pageNo" v-model="page.pageNo"
:total="page.total" :total="page.total"
:page-size.sync="page.pageSize" :page-size.sync="page.pageSize"
:page-size-options="[3, 9, 27, 45]" :totalContent='false'
:page-size-options="[10, 20, 30, 50]"
@change="onPageChange" @change="onPageChange"
align="center"
/> />
</div> </div>
</main> </main>
@ -199,6 +203,7 @@
</template> </template>
<script> <script>
import { SearchIcon } from 'tdesign-icons-vue';
import NewNav from '@/pages/index/components/new-nav/index.vue'; import NewNav from '@/pages/index/components/new-nav/index.vue';
import Footer from '@/pages/index/components/footer/index.vue'; import Footer from '@/pages/index/components/footer/index.vue';
import BreadcrumbNav from '@/pages/index/components/breadcrumb/index.vue'; import BreadcrumbNav from '@/pages/index/components/breadcrumb/index.vue';
@ -212,6 +217,7 @@ export default {
Footer, Footer,
BreadcrumbNav, BreadcrumbNav,
XqscPublish, XqscPublish,
SearchIcon,
}, },
data() { data() {
return { return {
@ -237,7 +243,7 @@ export default {
// //
page: { page: {
pageNo: 1, pageNo: 1,
pageSize: 9, pageSize: 10,
total: 0, total: 0,
}, },
// //
@ -445,8 +451,7 @@ export default {
// //
.secondary-nav { .secondary-nav {
background: #fff; border-bottom: none;
border-bottom: 1px solid #eee;
} }
.secondary-nav-content { .secondary-nav-content {
@ -454,60 +459,53 @@ export default {
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
max-width: 1400px; max-width: 1400px;
padding: 0 20px; padding: 20px 20px 0;
margin: 0 auto; margin: 0 auto;
} }
.nav-tabs { .nav-tabs {
display: flex; display: flex;
gap: 8px; gap: 40px;
width: 596px;
height: 42px;
}
.nav-right {
display: flex;
align-items: center;
gap: 20px;
} }
.nav-tab { .nav-tab {
position: relative; position: relative;
padding: 12px 20px; min-width: max-content;
font-size: 14px; height: 42px;
color: #666; padding: 8px 16px;
font-size: 18px;
font-weight: 500;
color: #003B1A;
cursor: pointer; cursor: pointer;
background: transparent; background: transparent;
border: none; border-radius: 32px;
border-bottom: 2px solid transparent;
transition: all 0.3s; transition: all 0.3s;
&::after {
position: absolute;
bottom: 0;
left: 50%;
width: 0;
height: 2px;
background: linear-gradient(90deg, #009a29, #48C666);
border-radius: 1px;
content: '';
transform: translateX(-50%);
transition: all 0.3s ease;
}
&:hover { &:hover {
color: #009a29; color: #009a29;
&::after {
width: 60%;
}
} }
&.active { &.active {
color: #009a29; background: #8CFFCE;
box-shadow: inset 0 0 0 1px #00B96B;
&::after {
width: 100%;
}
} }
} }
.publish-btn { .publish-btn {
padding: 8px 24px; width: 220px;
font-size: 14px; height: 42px;
font-weight: 500; line-height: 26px;
padding: 8px 16px;
font-size: 18px;
font-weight: 400;
color: #fff; color: #fff;
cursor: pointer; cursor: pointer;
background: linear-gradient(135deg, #009a29 0%, #48C666 100%); background: linear-gradient(135deg, #009a29 0%, #48C666 100%);
@ -529,6 +527,7 @@ export default {
.content-area { .content-area {
display: flex; display: flex;
gap: 20px; gap: 20px;
align-items: stretch;
} }
// //
@ -536,7 +535,6 @@ export default {
position: sticky; position: sticky;
top: 104px; top: 104px;
width: 220px; width: 220px;
height: fit-content;
flex-shrink: 0; flex-shrink: 0;
} }
@ -595,12 +593,11 @@ export default {
} }
.filter-section { .filter-section {
padding-bottom: 20px;
margin-bottom: 20px; margin-bottom: 20px;
border-bottom: 1px dashed #e0e0e0; border-bottom: 1px dashed #e0e0e0;
&:last-child { &:last-child {
padding-bottom: 0; padding: 10px 0;
margin-bottom: 0; margin-bottom: 0;
border-bottom: none; border-bottom: none;
} }
@ -631,92 +628,30 @@ export default {
} }
} }
.filter-buttons {
display: flex;
gap: 8px;
margin-top: 16px;
margin-bottom: 16px;
.t-button {
flex: 1;
}
}
// //
.demand-list { .demand-list {
flex: 1; flex: 1;
min-width: 0; min-width: 0;
} }
.list-header {
display: flex;
padding: 0 8px;
margin-bottom: 20px;
justify-content: space-between;
align-items: center;
}
.list-title-box {
display: flex;
align-items: center;
gap: 10px;
.list-icon {
font-size: 24px;
}
.list-title {
font-size: 22px;
font-weight: 600;
color: #333;
background: linear-gradient(135deg, #333 0%, #009a29 100%);
background-clip: text;
-webkit-text-fill-color: transparent;
}
}
.list-right {
display: flex;
align-items: center;
}
.list-count { .list-count {
display: flex;
align-items: center;
gap: 8px;
font-size: 14px; font-size: 14px;
color: #999; font-weight: 400;
color: #6B8575;
.count-dot {
width: 8px;
height: 8px;
background: linear-gradient(135deg, #009a29, #48C666);
border-radius: 50%;
animation: pulse 2s infinite;
}
}
@keyframes pulse {
0%, 100% {
opacity: 1;
}
50% {
opacity: 0.5;
}
} }
// //
.demand-grid { .demand-grid {
display: grid; display: grid;
grid-template-columns: repeat(2, 1fr); grid-template-columns: repeat(2, 1fr);
gap: 20px; gap: 24px;
} }
.demand-card { .demand-card {
position: relative; position: relative;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
padding: 20px; overflow: hidden;
background: #fff; background: #fff;
border-radius: 12px; border-radius: 12px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06); box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
@ -725,40 +660,71 @@ export default {
&.highlight-card { &.highlight-card {
animation: highlight-pulse 3s ease-out; animation: highlight-pulse 3s ease-out;
} }
&::before {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 3px;
background: linear-gradient(90deg, #009a29, #48C666);
content: '';
transform: scaleX(0);
transform-origin: left;
transition: transform 0.3s ease;
}
&:hover {
transform: translateY(-4px);
box-shadow: 0 8px 24px rgba(0, 154, 41, 0.15);
&::before {
transform: scaleX(1);
}
}
} }
.card-header { .card-header {
margin-bottom: 12px; position: relative;
padding: 16px;
height: 70px;
&::after {
position: absolute;
right: 16px;
bottom: -6px;
left: 16px;
height: 1px;
background: #E8F0EC;
content: '';
}
}
.card-title-box {
display: flex;
justify-content: space-between;
}
.card-title-text {
flex: 1;
min-width: 0;
}
.card-title-row {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 8px;
}
.card-title-sub {
display: flex;
gap: 12px;
justify-content: space-between;
}
.card-company {
display: flex;
align-items: center;
gap: 8px;
}
.company-name {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 14px;
color: #6B8575;
font-weight: 400;
} }
.demand-title { .demand-title {
margin-bottom: 8px; flex: 1;
font-size: 18px; overflow: hidden;
font-weight: 600; font-size: 16px;
line-height: 1.4; font-weight: 500;
color: #333; line-height: 24px;
color: #003B1A;
text-overflow: ellipsis;
white-space: nowrap;
&.urgent { &.urgent {
color: #d25f00; color: #d25f00;
@ -767,31 +733,30 @@ export default {
.demand-company { .demand-company {
font-size: 14px; font-size: 14px;
color: #666; color: #6B8575;
} }
.card-content { .card-content {
flex: 1; padding: 16px;
margin-bottom: 12px;
} }
.card-tags { .card-tags {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
gap: 8px; gap: 8px;
margin-bottom: 12px;
} }
.tag { .tag {
padding: 2px 8px; padding: 2px 8px;
font-size: 12px; font-size: 13px;
color: #2e7d32; font-weight: 400;
background: #dcf9e2; color: #00B96B;
background: #EEFAE2;
border-radius: 4px; border-radius: 4px;
} }
.card-desc { .card-desc {
display: box; display: block;
height: 70px; height: 70px;
overflow: hidden; overflow: hidden;
font-size: 14px; font-size: 14px;
@ -799,15 +764,25 @@ export default {
color: #666; color: #666;
text-overflow: ellipsis; text-overflow: ellipsis;
-webkit-line-clamp: 3; -webkit-line-clamp: 3;
box-orient: vertical;
} }
.card-footer { .card-footer {
position: relative;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
padding-top: 14px; padding: 14px 16px;
border-top: 1px dashed #979797; height: 64px;
&::before {
position: absolute;
top: 0;
right: 16px;
left: 16px;
height: 1px;
background: #E8F0EC;
content: '';
}
} }
.card-budget { .card-budget {
@ -823,8 +798,24 @@ export default {
.budget-value { .budget-value {
font-size: 20px; font-size: 20px;
font-weight: 700; font-weight: 600;
color: #D25F00; color: #FF4D4F;
}
.card-actions {
display: flex;
height: 32px;
padding: 6px 12px;
border-radius: 4px;
border: 1px solid #00b96b;
color: #00b96b;
font-size: 14px;
font-weight: 400;
&:hover {
background: rgba(0, 154, 41, 0.1);
cursor: pointer;
}
} }
// //
@ -833,26 +824,20 @@ export default {
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
min-height: 400px; width: 100%;
min-height: 300px;
padding: 40px; padding: 40px;
background: #fff; background: #fff;
border-radius: 12px; border-radius: 12px;
animation: fadeIn 0.5s ease; animation: fadeIn 0.5s ease;
.empty-illustration { .empty-icon {
margin-bottom: 20px; margin-bottom: 16px;
font-size: 64px; font-size: 48px;
color: #d0d0d0;
} }
.empty-text { p {
margin: 0 0 8px;
font-size: 18px;
font-weight: 600;
color: #333;
}
.empty-hint {
margin: 0;
font-size: 14px; font-size: 14px;
color: #999; color: #999;
} }
@ -904,10 +889,28 @@ export default {
} }
// //
.pagination-total {
font-size: 16px;
color: #666;
}
.pagination-box { .pagination-box {
display: flex; display: flex;
align-items: center;
justify-content: center; justify-content: center;
padding-top: 32px; padding-top: 32px;
gap: 10px;
::v-deep .t-pagination {
display: flex !important;
justify-content: center;
flex-wrap: wrap;
width: initial;
.t-input.t-is-readonly {
width: 110px;
}
}
} }
// //
@ -927,8 +930,8 @@ export default {
} }
@media (max-width: 1200px) { @media (max-width: 1200px) {
.demand-grid { .demand-card {
grid-template-columns: 1fr; width: calc((100% - 20px) / 2);
} }
} }
@ -979,32 +982,30 @@ export default {
width: 100%; width: 100%;
} }
.list-header {
flex-direction: column;
gap: 12px;
align-items: flex-start;
}
.demand-grid { .demand-grid {
grid-template-columns: 1fr; grid-template-columns: 1fr;
gap: 12px; gap: 12px;
} }
.demand-card { .demand-card {
padding: 16px;
}
.card-footer {
flex-direction: column;
gap: 12px;
align-items: flex-start;
}
.card-actions {
width: 100%; width: 100%;
} }
.card-actions .t-button { .card-header {
padding: 12px;
}
.card-content {
padding: 12px;
}
.card-footer {
padding: 12px;
flex-direction: column;
gap: 12px;
}
.card-actions {
width: 100%; width: 100%;
} }
@ -1032,12 +1033,12 @@ export default {
font-size: 13px; font-size: 13px;
} }
.list-title-box .list-title { .filter-sidebar-content {
font-size: 18px; padding: 12px;
} }
.demand-title { .card-title-main {
font-size: 16px; font-size: 14px;
} }
.card-desc { .card-desc {