1293 lines
27 KiB
Vue
1293 lines
27 KiB
Vue
<template>
|
||
<div class="xqsc-container portal-page-shell portal-market-figma-page">
|
||
<div class="portal-figma-scale-viewport">
|
||
<div class="portal-figma-scale-stage" ref="figmaStage">
|
||
<!-- 面包屑导航 -->
|
||
<!-- <BreadcrumbNav currentPage="碳需求市场" /> -->
|
||
|
||
<!-- 二级菜单 -->
|
||
<div class="secondary-nav">
|
||
<div class="secondary-nav-content">
|
||
<div class="nav-tabs">
|
||
<button
|
||
v-for="tab in navTabs"
|
||
:key="tab.path"
|
||
:class="['nav-tab', { active: isActiveTab(tab.path) }]"
|
||
@click="goToTab(tab)"
|
||
>
|
||
{{ tab.label }}
|
||
</button>
|
||
</div>
|
||
<div class="nav-right">
|
||
<span class="list-count">共 {{ page.total }} 条需求</span>
|
||
<button class="publish-btn" @click="handlePublish">免费发布需求</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<main class="xqsc-main">
|
||
<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">
|
||
<div class="filter-toggle" @click="filterCollapsed = !filterCollapsed">
|
||
<span class="toggle-text">筛选</span>
|
||
<span class="toggle-icon">{{ filterCollapsed ? '▼' : '▲' }}</span>
|
||
</div>
|
||
<div :class="['filter-sidebar-content', { collapsed: filterCollapsed }]">
|
||
<!-- 内容搜索 -->
|
||
<div class="filter-section">
|
||
<div class="filter-title">内容搜索</div>
|
||
<t-input v-model="filter.nr" placeholder="请输入关键词" @enter="onSearch">
|
||
<template #suffix-icon>
|
||
<SearchIcon />
|
||
</template>
|
||
</t-input>
|
||
</div>
|
||
|
||
<!-- 服务地区 -->
|
||
<div class="filter-section">
|
||
<div class="filter-title">服务地区</div>
|
||
<t-select v-model="filter.dq" :options="fwfwOptions" placeholder="请选择" clearable style="width: 100%" @change="onSearch" />
|
||
</div>
|
||
|
||
<!-- 需求类型 -->
|
||
<div class="filter-section">
|
||
<div class="filter-title">需求类型</div>
|
||
<div class="filter-options">
|
||
<t-checkbox-group v-model="filter.fwlxjh" :options="xqlxOptions" @change="onSearch" />
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 所属行业 -->
|
||
<div class="filter-section">
|
||
<div class="filter-title">所属行业</div>
|
||
<div class="filter-options">
|
||
<t-checkbox-group v-model="filter.sshy" :options="sshyDmOptions" @change="onSearch" />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</aside>
|
||
</div>
|
||
|
||
<!-- 分页 -->
|
||
<div class="pagination-box" v-if="page.total > 0">
|
||
<div class="pagination-total">共 {{ page.total }} 条数据</div>
|
||
<t-pagination
|
||
v-model="page.pageNo"
|
||
:total="page.total"
|
||
:page-size.sync="page.pageSize"
|
||
:totalContent='false'
|
||
:page-size-options="[10, 20, 30, 50]"
|
||
@change="onPageChange"
|
||
align="center"
|
||
/>
|
||
</div>
|
||
</main>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 发布需求抽屉 -->
|
||
<XqscPublish
|
||
:visible.sync="publishVisible"
|
||
@success="onPublishSuccess"
|
||
/>
|
||
|
||
<!-- 联系服务弹窗 -->
|
||
<t-dialog
|
||
:closeOnOverlayClick="false"
|
||
header="联系客户"
|
||
:visible.sync="contactVisible"
|
||
@confirm="onContactConfirm"
|
||
:onClose="onContactClose"
|
||
class="global-dialog"
|
||
attach="body"
|
||
>
|
||
<div class="dialog-line">
|
||
<div class="dialog-line-title">联系人:</div>
|
||
<div class="dialog-line-text">{{ contactData.lxr }}</div>
|
||
</div>
|
||
<div class="dialog-line">
|
||
<div class="dialog-line-title">联系电话:</div>
|
||
<div class="dialog-line-text">{{ contactData.lxdh }}</div>
|
||
</div>
|
||
<div class="dialog-line">
|
||
<div class="dialog-line-title">电子邮箱:</div>
|
||
<div class="dialog-line-text">{{ contactData.email }}</div>
|
||
</div>
|
||
</t-dialog>
|
||
|
||
<!-- 提示弹窗 -->
|
||
<t-dialog
|
||
:closeOnOverlayClick="false"
|
||
header="提示"
|
||
body="请先进行企业入驻"
|
||
:visible.sync="rzVisible"
|
||
@confirm="onRzConfirm"
|
||
:onClose="onRzClose"
|
||
:cancelBtn="null"
|
||
class="global-dialog"
|
||
/>
|
||
|
||
<!-- 发布成功弹窗 -->
|
||
<t-dialog
|
||
:closeOnOverlayClick="false"
|
||
body="发布申请成功,请等待审核,是否继续发布?"
|
||
:visible.sync="publishSuccessVisible"
|
||
@confirm="onPublishSuccessConfirm"
|
||
@cancel="onPublishSuccessCancel"
|
||
:onClose="onPublishSuccessClose"
|
||
cancelBtn="返回"
|
||
confirmBtn="继续发布"
|
||
class="global-dialog"
|
||
/>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import { SearchIcon } from 'tdesign-icons-vue';
|
||
import NewNav from '@/pages/index/components/new-nav/index.vue';
|
||
import BreadcrumbNav from '@/pages/index/components/breadcrumb/index.vue';
|
||
import XqscPublish from './components/XqscPublish.vue';
|
||
import api from '@/pages/index/api/fwsc/index.js';
|
||
import { scrollPortalContentToTop } from '@/pages/index/utils/portal-scroll-mode';
|
||
import portalFigmaScaleMixin from '@/pages/index/utils/portal-figma-scale-mixin';
|
||
import comingSoonMixin from '@/pages/index/utils/coming-soon-mixin';
|
||
|
||
export default {
|
||
name: 'XqscPage',
|
||
mixins: [portalFigmaScaleMixin, comingSoonMixin],
|
||
components: {
|
||
NewNav,
|
||
BreadcrumbNav,
|
||
XqscPublish,
|
||
SearchIcon,
|
||
},
|
||
data() {
|
||
return {
|
||
navTabs: [
|
||
{ label: '碳服务市场', path: '/tfwsc' },
|
||
{ label: '碳需求市场', path: '/txqsc' },
|
||
{ label: '碳数据市场', path: '/tsjsc' },
|
||
{ label: '碳金融市场', path: '/tjrsc', disable: true },
|
||
],
|
||
// 筛选条件
|
||
filter: {
|
||
fwlxjh: [],
|
||
sshy: [],
|
||
dq: '',
|
||
nr: '',
|
||
},
|
||
// 代码表选项
|
||
xqlxOptions: [],
|
||
sshyDmOptions: [],
|
||
fwfwOptions: [],
|
||
// 卡片列表
|
||
cardList: [],
|
||
// 分页
|
||
page: {
|
||
pageNo: 1,
|
||
pageSize: 10,
|
||
total: 0,
|
||
},
|
||
// 加载状态
|
||
loading: false,
|
||
// 发布抽屉
|
||
publishVisible: false,
|
||
// 联系弹窗
|
||
contactVisible: false,
|
||
contactData: {},
|
||
// 入驻提示弹窗
|
||
rzVisible: false,
|
||
// 发布成功弹窗
|
||
publishSuccessVisible: false,
|
||
// 移动端筛选折叠状态
|
||
filterCollapsed: true,
|
||
};
|
||
},
|
||
mounted() {
|
||
this.loadDmList();
|
||
this.searchList();
|
||
// 检查是否需要直接打开发布面板
|
||
if (this.$route.query.publish === '1') {
|
||
this.handlePublish();
|
||
}
|
||
},
|
||
methods: {
|
||
// 加载代码表
|
||
loadDmList() {
|
||
this.xqlxoptionsSearch();
|
||
this.sshyoptionsSearch();
|
||
this.fwfwoptionsSearch();
|
||
},
|
||
async xqlxoptionsSearch() {
|
||
try {
|
||
const res = await api.dms2mc('xqlx', {});
|
||
this.xqlxOptions = res.data || [];
|
||
} catch (error) {
|
||
this.xqlxOptions = [];
|
||
}
|
||
},
|
||
async sshyoptionsSearch() {
|
||
try {
|
||
const res = await api.dms2mc('sshy', {});
|
||
this.sshyDmOptions = res.data || [];
|
||
} catch (error) {
|
||
this.sshyDmOptions = [];
|
||
}
|
||
},
|
||
async fwfwoptionsSearch() {
|
||
try {
|
||
const res = await api.dms2mc('xzqh', {});
|
||
this.fwfwOptions = res.data || [];
|
||
} catch (error) {
|
||
this.fwfwOptions = [];
|
||
}
|
||
},
|
||
// 搜索列表
|
||
async searchList() {
|
||
this.loading = true;
|
||
this.cardList = [];
|
||
const targetId = this.$route.query.id || '';
|
||
try {
|
||
const prame = {
|
||
ywlxDm: '02',
|
||
...this.filter,
|
||
...this.page,
|
||
};
|
||
if (prame.dq === '000000') {
|
||
prame.dq = '';
|
||
}
|
||
// URL携带id:按id精确查询单条
|
||
if (targetId) {
|
||
prame.gxUuid = targetId;
|
||
}
|
||
const { data } = await api.gxxxList(prame);
|
||
if (data.records) {
|
||
data.records.map((item) => {
|
||
if (item.bqjh) {
|
||
item.bqjh = item.bqjh.split(',');
|
||
}
|
||
if (item.fwlxjh) {
|
||
item.fwlxbqList = item.fwlxjh.split(',');
|
||
} else {
|
||
item.fwlxbqList = [];
|
||
}
|
||
});
|
||
}
|
||
this.cardList = data.records || [];
|
||
this.page.total = Number(data.total || 0);
|
||
// 数据渲染后定位到对应项
|
||
if (targetId) {
|
||
this.scrollToItem(targetId);
|
||
}
|
||
} catch (error) {
|
||
this.cardList = [];
|
||
this.page.total = 0;
|
||
console.error('获取需求列表失败', error);
|
||
} finally {
|
||
this.loading = false;
|
||
}
|
||
},
|
||
// 重置筛选
|
||
onReset() {
|
||
this.filter = {
|
||
fwlxjh: [],
|
||
sshy: [],
|
||
dq: '',
|
||
nr: '',
|
||
};
|
||
this.page.pageNo = 1;
|
||
this.searchList();
|
||
},
|
||
// 搜索
|
||
onSearch() {
|
||
this.page.pageNo = 1;
|
||
this.searchList();
|
||
},
|
||
onPageChange(pageInfo) {
|
||
this.page.pageNo = pageInfo.current;
|
||
this.page.pageSize = pageInfo.pageSize;
|
||
scrollPortalContentToTop();
|
||
this.searchList();
|
||
},
|
||
// 滚动到指定项并高亮
|
||
scrollToItem(gxUuid) {
|
||
this.$nextTick(() => {
|
||
const targetCard = this.cardList.find(card => card.gxUuid === gxUuid);
|
||
if (targetCard) {
|
||
const cardElement = document.querySelector(`[data-gx-uuid="${gxUuid}"]`);
|
||
if (cardElement) {
|
||
cardElement.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||
cardElement.classList.add('highlight-card');
|
||
setTimeout(() => {
|
||
cardElement.classList.remove('highlight-card');
|
||
}, 3000);
|
||
}
|
||
}
|
||
});
|
||
},
|
||
// 处理发布
|
||
handlePublish() {
|
||
const yhxx = window.sessionStorage.getItem('yhxx');
|
||
if (yhxx) {
|
||
const yhxxData = JSON.parse(yhxx);
|
||
if (yhxxData.gxdtRzbz === 'Y') {
|
||
this.publishVisible = true;
|
||
} else {
|
||
this.rzVisible = true;
|
||
}
|
||
} else {
|
||
this.rzVisible = true;
|
||
}
|
||
},
|
||
// 联系客户
|
||
handleContact(card) {
|
||
this.contactData = {
|
||
lxr: card.lxr || '',
|
||
lxdh: card.lxdh || '',
|
||
email: card.email || '',
|
||
};
|
||
this.contactVisible = true;
|
||
},
|
||
// 发布成功回调
|
||
onPublishSuccess() {
|
||
this.publishSuccessVisible = true;
|
||
},
|
||
// 导航相关
|
||
isActiveTab(path) {
|
||
return this.$route.path === path;
|
||
},
|
||
goToTab({path, disable}) {
|
||
if (disable) {
|
||
this.showComingSoon();
|
||
return
|
||
}
|
||
this.$router.push(path);
|
||
},
|
||
// 弹窗回调
|
||
onContactConfirm() {
|
||
this.contactVisible = false;
|
||
},
|
||
onContactClose() {
|
||
this.contactVisible = false;
|
||
},
|
||
onRzConfirm() {
|
||
this.rzVisible = false;
|
||
},
|
||
onRzClose() {
|
||
this.rzVisible = false;
|
||
},
|
||
onPublishSuccessConfirm() {
|
||
this.publishSuccessVisible = false;
|
||
this.publishVisible = true;
|
||
},
|
||
onPublishSuccessCancel() {
|
||
this.publishSuccessVisible = false;
|
||
this.$router.push('/txqsc');
|
||
},
|
||
onPublishSuccessClose() {
|
||
this.publishSuccessVisible = false;
|
||
},
|
||
},
|
||
};
|
||
</script>
|
||
|
||
<style lang="less" scoped>
|
||
@import '../../styles/home-figma-variables.less';
|
||
|
||
.xqsc-container {
|
||
background: #f5f5f5;
|
||
.portal-figma-scale-page();
|
||
}
|
||
|
||
.xqsc-main {
|
||
width: 100%;
|
||
max-width: 1400px;
|
||
padding: 20px;
|
||
margin: 0 auto;
|
||
}
|
||
|
||
// 二级菜单
|
||
.secondary-nav {
|
||
border-bottom: none;
|
||
}
|
||
|
||
.secondary-nav-content {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
max-width: 1400px;
|
||
padding: 20px 20px 0;
|
||
margin: 0 auto;
|
||
}
|
||
|
||
.nav-tabs {
|
||
display: flex;
|
||
gap: 40px;
|
||
width: 596px;
|
||
height: 42px;
|
||
}
|
||
|
||
.nav-right {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 20px;
|
||
}
|
||
|
||
.nav-tab {
|
||
position: relative;
|
||
min-width: max-content;
|
||
height: 42px;
|
||
padding: 8px 16px;
|
||
font-size: 18px;
|
||
font-weight: 500;
|
||
color: #003B1A;
|
||
cursor: pointer;
|
||
background: transparent;
|
||
border-radius: 32px;
|
||
transition: all 0.3s;
|
||
|
||
&:hover {
|
||
color: #009a29;
|
||
}
|
||
|
||
&.active {
|
||
background: #8CFFCE;
|
||
box-shadow: inset 0 0 0 1px #00B96B;
|
||
}
|
||
}
|
||
|
||
.publish-btn {
|
||
width: 220px;
|
||
height: 42px;
|
||
line-height: 26px;
|
||
padding: 8px 16px;
|
||
font-size: 18px;
|
||
font-weight: 400;
|
||
color: #fff;
|
||
cursor: pointer;
|
||
background: linear-gradient(135deg, #009a29 0%, #48C666 100%);
|
||
border: none;
|
||
border-radius: 6px;
|
||
box-shadow: 0 4px 12px rgba(0, 154, 41, 0.25);
|
||
transition: all 0.3s ease;
|
||
|
||
&:hover {
|
||
transform: translateY(-2px);
|
||
box-shadow: 0 6px 16px rgba(0, 154, 41, 0.35);
|
||
}
|
||
|
||
&:active {
|
||
transform: translateY(0);
|
||
}
|
||
}
|
||
|
||
.content-area {
|
||
display: flex;
|
||
gap: 20px;
|
||
align-items: stretch;
|
||
}
|
||
|
||
// 左侧筛选栏
|
||
.filter-sidebar {
|
||
position: sticky;
|
||
top: 104px;
|
||
width: 220px;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.filter-sidebar-content {
|
||
padding: 20px;
|
||
background: #fff;
|
||
border-radius: 12px;
|
||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
|
||
}
|
||
|
||
// 移动端筛选栏折叠
|
||
.filter-toggle {
|
||
display: none;
|
||
}
|
||
|
||
@media (max-width: 768px) {
|
||
.filter-toggle {
|
||
display: flex;
|
||
padding: 12px;
|
||
margin-bottom: 8px;
|
||
cursor: pointer;
|
||
background: #fff;
|
||
border-radius: 8px;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
|
||
.toggle-text {
|
||
font-size: 14px;
|
||
font-weight: 600;
|
||
color: #333;
|
||
}
|
||
|
||
.toggle-icon {
|
||
font-size: 18px;
|
||
color: #666;
|
||
transition: transform 0.3s;
|
||
}
|
||
|
||
&.collapsed .toggle-icon {
|
||
transform: rotate(-90deg);
|
||
}
|
||
}
|
||
|
||
.filter-sidebar-content {
|
||
max-height: 1000px;
|
||
padding: 20px;
|
||
overflow: hidden;
|
||
transition: max-height 0.3s ease, padding 0.3s ease;
|
||
}
|
||
|
||
.filter-sidebar-content.collapsed {
|
||
max-height: 0;
|
||
padding-top: 0;
|
||
padding-bottom: 0;
|
||
}
|
||
}
|
||
|
||
.filter-section {
|
||
margin-bottom: 20px;
|
||
border-bottom: 1px dashed #e0e0e0;
|
||
|
||
&:last-child {
|
||
padding: 10px 0;
|
||
margin-bottom: 0;
|
||
border-bottom: none;
|
||
}
|
||
}
|
||
|
||
.filter-title {
|
||
display: flex;
|
||
margin-bottom: 12px;
|
||
font-size: 14px;
|
||
font-weight: 600;
|
||
color: #333;
|
||
align-items: center;
|
||
gap: 6px;
|
||
|
||
&::before {
|
||
width: 4px;
|
||
height: 14px;
|
||
background: linear-gradient(180deg, #009a29, #48C666);
|
||
border-radius: 2px;
|
||
content: '';
|
||
}
|
||
}
|
||
|
||
.filter-options {
|
||
/deep/.t-checkbox__label {
|
||
font-size: 14px;
|
||
color: #666;
|
||
}
|
||
}
|
||
|
||
// 右侧需求列表
|
||
.demand-list {
|
||
flex: 1;
|
||
min-width: 0;
|
||
}
|
||
|
||
.list-count {
|
||
font-size: 14px;
|
||
font-weight: 400;
|
||
color: #6B8575;
|
||
}
|
||
|
||
// 需求卡片网格
|
||
.demand-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(2, 1fr);
|
||
gap: 24px;
|
||
}
|
||
|
||
.demand-card {
|
||
position: relative;
|
||
display: flex;
|
||
flex-direction: column;
|
||
overflow: hidden;
|
||
background: #fff;
|
||
border-radius: 12px;
|
||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
|
||
transition: all 0.3s ease;
|
||
|
||
&.highlight-card {
|
||
animation: highlight-pulse 3s ease-out;
|
||
}
|
||
}
|
||
|
||
.card-header {
|
||
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 {
|
||
flex: 1;
|
||
overflow: hidden;
|
||
font-size: 16px;
|
||
font-weight: 500;
|
||
line-height: 24px;
|
||
color: #003B1A;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
|
||
&.urgent {
|
||
color: #d25f00;
|
||
}
|
||
}
|
||
|
||
.demand-company {
|
||
font-size: 14px;
|
||
color: #6B8575;
|
||
}
|
||
|
||
.card-content {
|
||
padding: 16px;
|
||
}
|
||
|
||
.card-tags {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 8px;
|
||
}
|
||
|
||
.tag {
|
||
padding: 2px 8px;
|
||
font-size: 13px;
|
||
font-weight: 400;
|
||
color: #00B96B;
|
||
background: #EEFAE2;
|
||
border-radius: 4px;
|
||
}
|
||
|
||
.card-desc {
|
||
display: block;
|
||
height: 70px;
|
||
overflow: hidden;
|
||
font-size: 14px;
|
||
line-height: 1.6;
|
||
color: #666;
|
||
text-overflow: ellipsis;
|
||
-webkit-line-clamp: 3;
|
||
}
|
||
|
||
.card-footer {
|
||
position: relative;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 14px 16px;
|
||
height: 64px;
|
||
|
||
&::before {
|
||
position: absolute;
|
||
top: 0;
|
||
right: 16px;
|
||
left: 16px;
|
||
height: 1px;
|
||
background: #E8F0EC;
|
||
content: '';
|
||
}
|
||
}
|
||
|
||
.card-budget {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.budget-label {
|
||
margin-right: 8px;
|
||
font-size: 14px;
|
||
color: #666;
|
||
}
|
||
|
||
.budget-value {
|
||
font-size: 20px;
|
||
font-weight: 600;
|
||
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;
|
||
}
|
||
}
|
||
|
||
// 空状态
|
||
.empty-state {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 100%;
|
||
min-height: 300px;
|
||
padding: 40px;
|
||
background: #fff;
|
||
border-radius: 12px;
|
||
animation: fadeIn 0.5s ease;
|
||
|
||
.empty-icon {
|
||
margin-bottom: 16px;
|
||
font-size: 48px;
|
||
color: #d0d0d0;
|
||
}
|
||
|
||
p {
|
||
font-size: 14px;
|
||
color: #999;
|
||
}
|
||
}
|
||
|
||
// 加载状态
|
||
.loading-state {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
min-height: 400px;
|
||
padding: 40px;
|
||
background: #fff;
|
||
border-radius: 12px;
|
||
|
||
.loading-spinner {
|
||
width: 48px;
|
||
height: 48px;
|
||
margin-bottom: 16px;
|
||
border: 4px solid #e8f5e9;
|
||
border-top-color: #009a29;
|
||
border-radius: 50%;
|
||
animation: spin 1s linear infinite;
|
||
}
|
||
|
||
p {
|
||
margin: 0;
|
||
font-size: 14px;
|
||
color: #999;
|
||
}
|
||
}
|
||
|
||
@keyframes spin {
|
||
to {
|
||
transform: rotate(360deg);
|
||
}
|
||
}
|
||
|
||
@keyframes fadeIn {
|
||
from {
|
||
opacity: 0;
|
||
transform: translateY(10px);
|
||
}
|
||
to {
|
||
opacity: 1;
|
||
transform: translateY(0);
|
||
}
|
||
}
|
||
|
||
// 分页
|
||
.pagination-total {
|
||
font-size: 16px;
|
||
color: #666;
|
||
}
|
||
|
||
.pagination-box {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding-top: 32px;
|
||
gap: 16px;
|
||
width: 100%;
|
||
box-sizing: border-box;
|
||
|
||
::v-deep .t-pagination {
|
||
display: flex !important;
|
||
flex-wrap: wrap;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: auto;
|
||
max-width: 100%;
|
||
gap: 12px 16px;
|
||
|
||
.t-input.t-is-readonly {
|
||
width: 110px;
|
||
}
|
||
|
||
.t-pagination__select {
|
||
margin-right: 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 弹窗样式
|
||
.dialog-line {
|
||
display: flex;
|
||
margin-bottom: 16px;
|
||
}
|
||
|
||
.dialog-line-title {
|
||
flex-shrink: 0;
|
||
width: 80px;
|
||
color: #333;
|
||
}
|
||
|
||
.dialog-line-text {
|
||
color: #666;
|
||
}
|
||
|
||
@media (max-width: 1200px) {
|
||
.demand-card {
|
||
width: calc((100% - 20px) / 2);
|
||
}
|
||
}
|
||
|
||
@media (max-width: 768px) {
|
||
.xqsc-container {
|
||
overflow-x: hidden;
|
||
}
|
||
|
||
.xqsc-main {
|
||
padding: 12px;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.secondary-nav-content {
|
||
flex-direction: column;
|
||
align-items: stretch;
|
||
padding: 12px 16px;
|
||
gap: 12px;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.nav-tabs {
|
||
display: flex;
|
||
flex-wrap: nowrap;
|
||
align-items: center;
|
||
width: 100%;
|
||
max-width: 100%;
|
||
height: auto;
|
||
min-height: 42px;
|
||
padding-bottom: 4px;
|
||
overflow-x: auto;
|
||
overflow-y: hidden;
|
||
gap: 8px;
|
||
scrollbar-width: none;
|
||
-webkit-overflow-scrolling: touch;
|
||
|
||
&::-webkit-scrollbar {
|
||
display: none;
|
||
width: 0;
|
||
height: 0;
|
||
}
|
||
}
|
||
|
||
.nav-tab {
|
||
flex-shrink: 0;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
height: auto;
|
||
min-height: 40px;
|
||
padding: 10px 12px;
|
||
font-size: 13px;
|
||
line-height: 1.2;
|
||
white-space: nowrap;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.nav-right {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: stretch;
|
||
gap: 8px;
|
||
width: 100%;
|
||
}
|
||
|
||
.list-count {
|
||
width: 100%;
|
||
font-size: 14px;
|
||
line-height: 22px;
|
||
text-align: center;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.publish-btn {
|
||
width: 100%;
|
||
height: auto;
|
||
min-height: 44px;
|
||
padding: 10px 16px;
|
||
font-size: 15px;
|
||
line-height: 1.3;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.content-area {
|
||
flex-direction: column;
|
||
gap: 12px;
|
||
}
|
||
|
||
.filter-sidebar {
|
||
position: relative;
|
||
top: 0;
|
||
order: -1;
|
||
width: 100%;
|
||
}
|
||
|
||
.demand-list {
|
||
order: 0;
|
||
width: 100%;
|
||
}
|
||
|
||
.filter-sidebar-content {
|
||
padding: 12px;
|
||
}
|
||
|
||
.demand-grid {
|
||
grid-template-columns: 1fr;
|
||
gap: 12px;
|
||
}
|
||
|
||
.demand-card {
|
||
width: 100%;
|
||
}
|
||
|
||
.card-header {
|
||
padding: 12px;
|
||
}
|
||
|
||
.card-content {
|
||
padding: 12px;
|
||
}
|
||
|
||
.card-footer {
|
||
padding: 12px;
|
||
flex-direction: column;
|
||
gap: 12px;
|
||
}
|
||
|
||
.card-actions {
|
||
width: 100%;
|
||
}
|
||
|
||
.pagination-box {
|
||
flex-direction: column;
|
||
align-items: stretch;
|
||
padding-top: 16px;
|
||
padding-bottom: 32px;
|
||
gap: 12px;
|
||
}
|
||
|
||
.pagination-total {
|
||
width: 100%;
|
||
font-size: 14px;
|
||
line-height: 22px;
|
||
text-align: center;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.pagination-box ::v-deep .t-pagination {
|
||
display: flex !important;
|
||
flex-wrap: wrap !important;
|
||
align-items: center;
|
||
justify-content: center !important;
|
||
width: 100% !important;
|
||
max-width: 100%;
|
||
white-space: normal !important;
|
||
row-gap: 12px;
|
||
column-gap: 8px;
|
||
}
|
||
|
||
.pagination-box ::v-deep .t-pagination__total {
|
||
display: none;
|
||
}
|
||
|
||
.pagination-box ::v-deep .t-pagination__btn-prev {
|
||
order: 1;
|
||
}
|
||
|
||
.pagination-box ::v-deep .t-pagination__pager {
|
||
order: 2;
|
||
}
|
||
|
||
.pagination-box ::v-deep .t-pagination__btn-next {
|
||
order: 3;
|
||
}
|
||
|
||
.pagination-box ::v-deep .t-pagination__select {
|
||
order: 4;
|
||
flex: 0 0 auto;
|
||
width: auto;
|
||
max-width: none;
|
||
margin: 0 0 0 8px !important;
|
||
display: flex;
|
||
justify-content: center;
|
||
}
|
||
|
||
.pagination-box ::v-deep .t-pagination__select .t-select__wrap {
|
||
width: auto;
|
||
max-width: none;
|
||
}
|
||
|
||
.pagination-box ::v-deep .t-pagination__pager {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 6px;
|
||
max-width: 100%;
|
||
}
|
||
|
||
@mob-pagination-h: 32px;
|
||
|
||
.pagination-box ::v-deep .t-pagination__number {
|
||
min-width: @mob-pagination-h;
|
||
height: @mob-pagination-h;
|
||
line-height: @mob-pagination-h;
|
||
margin: 0;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.pagination-box ::v-deep .t-pagination__btn {
|
||
min-width: @mob-pagination-h;
|
||
width: @mob-pagination-h;
|
||
height: @mob-pagination-h;
|
||
line-height: @mob-pagination-h;
|
||
}
|
||
|
||
.pagination-box ::v-deep .t-pagination__select {
|
||
height: @mob-pagination-h;
|
||
align-items: center;
|
||
}
|
||
|
||
.pagination-box ::v-deep .t-pagination__select .t-select__wrap,
|
||
.pagination-box ::v-deep .t-pagination__select .t-input__wrap,
|
||
.pagination-box ::v-deep .t-pagination__select .t-input {
|
||
height: @mob-pagination-h !important;
|
||
min-height: @mob-pagination-h !important;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.pagination-box ::v-deep .t-pagination__select .t-input__inner {
|
||
height: @mob-pagination-h !important;
|
||
min-height: @mob-pagination-h !important;
|
||
line-height: @mob-pagination-h;
|
||
padding-top: 0;
|
||
padding-bottom: 0;
|
||
font-size: 13px;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.pagination-box ::v-deep .t-pagination__jump {
|
||
display: none !important;
|
||
}
|
||
|
||
.pagination-box ::v-deep .t-input.t-is-readonly {
|
||
width: auto;
|
||
min-width: 96px;
|
||
max-width: none;
|
||
}
|
||
}
|
||
|
||
@media (max-width: 480px) {
|
||
.xqsc-main {
|
||
padding: 8px;
|
||
}
|
||
|
||
.secondary-nav-content {
|
||
padding: 8px 12px;
|
||
}
|
||
|
||
.nav-tab {
|
||
padding: 8px 10px;
|
||
font-size: 12px;
|
||
}
|
||
|
||
.publish-btn {
|
||
padding: 8px;
|
||
font-size: 13px;
|
||
}
|
||
|
||
.filter-sidebar-content {
|
||
padding: 12px;
|
||
}
|
||
|
||
.card-title-main {
|
||
font-size: 14px;
|
||
}
|
||
|
||
.card-desc {
|
||
height: 60px;
|
||
font-size: 13px;
|
||
}
|
||
|
||
.budget-value {
|
||
font-size: 18px;
|
||
}
|
||
|
||
.pagination-box {
|
||
padding-bottom: 40px;
|
||
}
|
||
|
||
@mob-pagination-h-sm: 28px;
|
||
|
||
.pagination-box ::v-deep .t-pagination__number {
|
||
min-width: @mob-pagination-h-sm;
|
||
height: @mob-pagination-h-sm;
|
||
line-height: @mob-pagination-h-sm;
|
||
font-size: 13px;
|
||
}
|
||
|
||
.pagination-box ::v-deep .t-pagination__btn {
|
||
min-width: @mob-pagination-h-sm;
|
||
width: @mob-pagination-h-sm;
|
||
height: @mob-pagination-h-sm;
|
||
line-height: @mob-pagination-h-sm;
|
||
}
|
||
|
||
.pagination-box ::v-deep .t-pagination__select,
|
||
.pagination-box ::v-deep .t-pagination__select .t-select__wrap,
|
||
.pagination-box ::v-deep .t-pagination__select .t-input__wrap,
|
||
.pagination-box ::v-deep .t-pagination__select .t-input,
|
||
.pagination-box ::v-deep .t-pagination__select .t-input__inner {
|
||
height: @mob-pagination-h-sm !important;
|
||
min-height: @mob-pagination-h-sm !important;
|
||
line-height: @mob-pagination-h-sm;
|
||
}
|
||
}
|
||
|
||
@keyframes highlight-pulse {
|
||
0% {
|
||
box-shadow: 0 0 0 0 rgba(0, 154, 41, 0.4);
|
||
}
|
||
50% {
|
||
box-shadow: 0 0 20px 10px rgba(0, 154, 41, 0.2);
|
||
}
|
||
100% {
|
||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
|
||
}
|
||
}
|
||
</style>
|