This commit is contained in:
hrx 2026-09-02 11:30:14 +08:00
parent 1b53d2cb82
commit 7d2bb30e52
21 changed files with 5270 additions and 478 deletions

View File

@ -98,6 +98,7 @@
"lint-staged": "8.1.5",
"mockjs": "1.0.1-beta3",
"plop": "2.3.0",
"postcss": "^8.5.26",
"postcss-pxtorem": "^5.0.0",
"runjs": "4.3.2",
"sass": "1.39.0",
@ -106,6 +107,7 @@
"serve-static": "1.13.2",
"svg-sprite-loader": "4.1.3",
"svgo": "1.2.0",
"tailwindcss": "^2.2.19",
"vue-happy-scroll": "^2.1.1",
"vue-template-compiler": "2.6.10",
"webpack": "^4.47.0"

View File

@ -133,11 +133,18 @@ export default {
},
computed: {
shouldShowFloatingConsult() {
const path = this.$route && this.$route.path ? this.$route.path : ''
// hash www.ncmatch.cn
const hashPath = (window.location.hash || '').replace(/^#/, '')
const isHomePage = [
'/homePage/index',
'/homePage/indexLast',
'/ncmatchHome/index'
].includes(this.$route.path)
// '/homePage/indexLast',
].some(p => path === p || hashPath === p || hashPath.startsWith(p + '/'))
// ncmatch
const isNcmatchSubSite = window.location.host === 'www.ncmatch.cn'
|| window.location.host.endsWith('.ncmatch.cn')
if (isNcmatchSubSite) return false
return isHomePage || this.orgType === '2' || this.orgType === '3' || !this.userid
}
},

View File

@ -120,6 +120,16 @@ export const constantRoutes = [
title: 'H5合同智能审查案例',
component: () => import('@/views/H5/contractCase/index.vue'),
meta: { title: '合同智能审查', fullPath: '/h5HomePage/contract-case' }
},
{
path: 'consultDialogFull',
name: 'consultDialogFull',
title: 'H5咨询对话',
component: () => import('@/views/H5/consultDialogFullPreview/index.vue'),
meta: {
title: 'H5咨询对话',
fullPath: '/h5HomePage/consultDialogFull'
}
}
]
},
@ -283,19 +293,28 @@ export const constantRoutes = [
name: 'ncmatchSocietyNews',
meta: { title: '政社快讯', fullPath: '/ncmatch/societyNews', noCache: true }
},
// token市集
{
path: 'tokenMarket',
component: () => import('@/views/product/allProduct/index.vue'),
name: 'homePageTokenMarket',
component: () => import('@/views/Ncmatch/token.vue'),
name: 'ncmatchTokenMarket',
hidden: true,
meta: { title: 'TOKEN市集', onCache: true }
meta: { title: 'TOKEN市集', fullPath: '/ncmatch/tokenMarket', noCache: true }
},
// 云枢基座
{
path: 'cloudHub',
component: () => import('@/views/Ncmatch/CloudHub.vue'),
name: 'ncmatchCloudHub',
hidden: true,
meta: { title: '云枢基座', fullPath: '/ncmatch/cloudHub', noCache: true }
},
{
path: 'supplyAndDemandSquare',
component: () => import('@/views/homePage/ncmatch/supplyAndDemandSquare/index.vue'),
component: () => import('@/views/Ncmatch/supply_demand.vue'),
name: 'supplyAndDemandSquare',
hidden: true,
meta: { title: '算力供需广场', fullPath: '/ncmatch/supplyAndDemandSquare' }
meta: { title: '供需广场', fullPath: '/ncmatch/supplyAndDemandSquare' }
},
{

View File

@ -0,0 +1,627 @@
<template>
<div class="cloud-hub-page">
<!-- 内容区域 -->
<div class="hub-content">
<!-- 左侧分类导航 -->
<div class="hub-sidebar">
<div class="sidebar-section">
<!-- 搜索框 -->
<div class="input">
<el-input
v-model="searchKeyword"
class="product-search"
clearable
prefix-icon="el-icon-search"
placeholder="搜索产品名称、类型或描述"
></el-input>
</div>
<!-- 厂家筛选 -->
<div class="vendor-filter">
<!-- <div
class="vendor-item"
:class="{ active: !activeVendor }"
@click="switchVendor(null)"
>
<span class="vendor-text">全部</span>
</div> -->
<div
v-for="v in vendorOptions"
:key="v.key"
class="vendor-item"
:class="{ active: activeVendor === v.key }"
@click="switchVendor(v.key)"
>
<span class="vendor-text">{{ v.label }}</span>
</div>
</div>
<div class="section-title">产品分类</div>
<div class="category-chips">
<div
v-for="chip in displayedChips"
:key="chip.key"
class="chip-item"
:class="{ active: activeChipKey === chip.key }"
@click="switchChip(chip)"
>
<span class="chip-name">
<span v-if="chip.secTitle" class="chip-vendor-text">{{ chip.secTitle }}</span>
{{ chip.thrTitle }}
</span>
<span class="chip-count">{{ chip.count }}</span>
</div>
</div>
</div>
</div>
<!-- 右侧产品网格 -->
<div class="hub-main">
<div v-if="loading" class="loading-state">
<i class="el-icon-loading"></i>
<span>加载中...</span>
</div>
<div v-else-if="displayedProducts.length" class="product-grid">
<div
v-for="product in displayedProducts"
:key="product.id"
class="product-card"
@click="handleProductClick(product)"
>
<!-- 卡片头部图标 + 标题 + 类型 -->
<div class="product-header">
<div class="product-icon">
<img
v-if="product.iconUrl && !iconLoadFailed[product.id]"
:src="product.iconUrl"
:alt="product.name"
@error="handleIconError(product.id)"
>
<i v-else class="el-icon-cloudy"></i>
</div>
<div class="product-title">
<h3 class="product-name">{{ product.name }}</h3>
<span class="product-type">{{ product.type || '百度云' }}</span>
</div>
</div>
<!-- 产品描述 -->
<div class="product-desc">{{ product.description }}</div>
<!-- 卡片底部状态标签 + 查看详情按钮 -->
<div class="product-footer">
<span class="product-status">
{{ getStatusLabel(product) }}
</span>
<button class="detail-btn" @click.stop="handleDetailClick(product)">
查看详情
<i class="el-icon-arrow-right"></i>
</button>
</div>
</div>
</div>
<div v-else class="empty-state">
<div class="empty-icon">
<i class="el-icon-box"></i>
</div>
<p class="empty-text">{{ searchKeyword ? '没有匹配的产品' : '暂无产品数据' }}</p>
<span>可以切换分类或调整搜索关键词后再试</span>
</div>
</div>
</div>
</div>
</template>
<script>
import { reqNavList } from "@/api/newHome";
export default {
name: "BaseCloudProducts",
data() {
return {
panelData: [],
activeChipKey: null,
activeVendor: null, // secTitlenull
loading: false,
iconLoadFailed: {},
searchKeyword: '',
};
},
computed: {
// ""
jichuyunCategory() {
return this.panelData.find(item => item.firTitle === '基础云') || null;
},
// secMenu.secTitle
vendorOptions() {
if (!this.jichuyunCategory || !this.jichuyunCategory.secMenu) return [];
//
const seen = new Set();
const list = [];
this.jichuyunCategory.secMenu.forEach(sec => {
if (sec.secTitle && !seen.has(sec.secTitle)) {
seen.add(sec.secTitle);
list.push({ key: sec.secTitle, label: sec.secTitle });
}
});
return list;
},
// "" chips
categoryChips() {
if (!this.jichuyunCategory || !this.jichuyunCategory.secMenu) return [];
const chips = [];
this.jichuyunCategory.secMenu.forEach(sec => {
if (!sec.thrMenu || !sec.thrMenu.length) return;
sec.thrMenu
.filter(thr => thr.value && thr.value.length > 0)
.forEach(thr => {
chips.push({
key: thr.id || `${sec.id}_${thr.thrTitle}`,
thrTitle: thr.thrTitle,
secTitle: sec.secTitle,
secId: sec.id,
count: thr.value.length,
products: thr.value,
});
});
});
return chips;
},
// chips
displayedChips() {
if (!this.activeVendor) return this.categoryChips;
return this.categoryChips.filter(chip => chip.secTitle === this.activeVendor);
},
currentProducts() {
if (!this.activeChipKey) {
return this.allProducts;
}
const chip = this.categoryChips.find(c => c.key === this.activeChipKey);
return chip ? chip.products : [];
},
//
displayedProducts() {
const keyword = this.searchKeyword.trim().toLowerCase();
if (!keyword) return this.currentProducts;
return this.currentProducts.filter(product => {
return [
product.name,
product.type,
product.description
].join(' ').toLowerCase().includes(keyword);
});
},
allProducts() {
if (!this.categoryChips.length) return [];
return this.categoryChips.reduce((acc, chip) => acc.concat(chip.products), []);
},
},
async mounted() {
await this.loadNavData();
if (this.categoryChips.length) {
this.activeChipKey = this.categoryChips[0].key;
}
},
methods: {
async loadNavData() {
this.loading = true;
try {
const url_link = window.location.href.split('#')[0] + '#' + (window.location.pathname || '/homePage/index');
const response = await reqNavList({ url_link });
if (response.status && response.data && response.data.product_service) {
this.panelData = response.data.product_service;
}
} catch (error) {
console.error('加载基础云产品数据失败:', error);
} finally {
this.loading = false;
}
},
switchChip(chip) {
this.activeChipKey = chip.key;
},
//
switchVendor(secTitle) {
this.activeVendor = secTitle;
//
const chips = secTitle
? this.categoryChips.filter(c => c.secTitle === secTitle)
: this.categoryChips;
this.activeChipKey = chips.length ? chips[0].key : null;
},
//
getStatusLabel(product) {
if (product.label) {
const first = product.label.split(',')[0].trim();
if (first) return first;
}
return '稳定服务';
},
//
handleProductClick(product) {
console.log('点击产品:', product);
const userId = sessionStorage.getItem('userId');
if (product.url) {
if (userId) {
localStorage.setItem('redirectUrl', product.url);
localStorage.setItem('userRescourseUrl', product.listUrl);
this.$router.push({
name: 'baiduProductShow',
params: {
listUrl: product.listUrl,
url: product.url,
},
});
} else {
window.dispatchEvent(new Event('kboss-open-login-dialog'));
}
}
},
//
handleDetailClick(product) {
if (product.listUrl) {
window.open(product.listUrl, '_blank');
} else if (product.url) {
window.open(product.url, '_blank');
}
},
handleIconError(productId) {
this.$set(this.iconLoadFailed, productId, true);
},
},
};
</script>
<style lang="less" scoped>
.cloud-hub-page {
margin: 0 auto;
padding: 0 24px 40px;
background: #f8f9fb;
min-height: calc(100vh - 80px);
}
.hub-content {
display: flex;
gap: 20px;
padding-top: 24px;
}
/* ============= 左侧分类导航 ============= */
.hub-sidebar {
width: 240px;
flex-shrink: 0;
.sidebar-section {
background: #fff;
height: calc(100vh - 130px);
border-radius: 10px;
padding: 16px;
border: 1px solid #eef0f5;
}
.input {
margin-bottom: 12px;
.product-search {
/deep/ .el-input__inner {
height: 36px;
line-height: 36px;
border-radius: 10px;
background: #f6f8fc;
border-color: #e8edf5;
}
}
}
/* 厂家筛选区域 */
.vendor-filter {
display: flex;
flex-wrap: wrap;
gap: 6px;
margin-bottom: 12px;
}
.vendor-item {
display: inline-flex;
align-items: center;
gap: 5px;
padding: 4px 10px;
border-radius: 16px;
cursor: pointer;
font-size: 12px;
color: #6b7890;
background: #f0f4f8;
border: 1px solid transparent;
transition: all 0.2s;
&:hover {
border-color: currentColor;
}
&.active {
background: #eef3ff;
border-color: #1e6fff;
color: #1e6fff;
font-weight: 600;
}
}
.section-title {
font-size: 14px;
font-weight: 600;
color: #1a1a1a;
margin-bottom: 12px;
padding-bottom: 8px;
border-bottom: 1px solid #f0f0f0;
}
.category-chips {
display: flex;
flex-direction: column;
gap: 4px;
}
.chip-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 8px 12px;
border-radius: 6px;
cursor: pointer;
transition: all 0.2s;
border: 1px solid transparent;
&:hover {
background: rgba(30, 111, 255, 0.06);
color: #1e6fff;
}
&.active {
background: rgba(30, 111, 255, 0.1);
border-color: rgba(30, 111, 255, 0.2);
color: #1e6fff;
font-weight: 600;
.chip-count {
background: #1e6fff;
color: #fff;
}
}
.chip-name {
font-size: 13px;
display: inline-flex;
align-items: center;
gap: 6px;
}
.chip-vendor-text {
display: inline-block;
font-size: 11px;
font-weight: 600;
color: #1e6fff;
background: #eef3ff;
padding: 1px 6px;
border-radius: 4px;
flex-shrink: 0;
margin-right: 4px;
}
.chip-count {
background: #e8f0fe;
color: #6b7890;
font-size: 11px;
padding: 1px 7px;
border-radius: 10px;
min-width: 20px;
text-align: center;
}
}
}
/* ============= 右侧主区域 ============= */
.hub-main {
flex: 1;
min-width: 0;
.loading-state {
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
height: 200px;
color: #6b7890;
font-size: 14px;
}
.product-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 16px;
}
/* ===== 产品卡片新样式(参考用户提供) ===== */
.product-card {
background: #fff;
border: 1px solid #f0f0f0;
padding: 20px;
cursor: pointer;
transition: all 0.3s;
position: relative;
min-height: 178px;
overflow: hidden;
border-color: #edf1f7;
border-radius: 18px;
box-shadow: 0 10px 26px rgba(31, 45, 61, 0.06);
display: flex;
flex-direction: column;
justify-content: space-between;
//
&::before {
content: '';
position: absolute;
top: -40px;
right: -40px;
width: 110px;
height: 110px;
border-radius: 50%;
background: #f0f6ff;
pointer-events: none;
}
&:hover {
transform: translateY(-4px);
box-shadow: 0 16px 32px rgba(31, 45, 61, 0.1);
border-color: #1e6fff;
}
.product-header {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 12px;
.product-icon {
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
img {
width: 100%;
height: 100%;
object-fit: contain;
}
i {
font-size: 32px;
color: #1e6fff;
}
}
.product-title {
flex: 1;
display: flex;
flex-direction: column;
gap: 4px;
min-width: 0;
.product-name {
margin: 0;
font-size: 16px;
font-weight: 600;
color: #111827;
line-height: 1.3;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.product-type {
font-size: 12px;
color: #6b7890;
background: #f0f4f8;
padding: 1px 8px;
border-radius: 10px;
display: inline-block;
width: fit-content;
}
}
}
.product-desc {
font-size: 14px;
color: #4a5568;
line-height: 1.6;
margin: 4px 0 8px;
flex: 1;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.product-footer {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 8px;
padding-top: 12px;
border-top: 1px solid #f0f4f8;
.product-status {
font-size: 13px;
color: #10b981;
background: #ecfdf5;
padding: 2px 12px;
border-radius: 12px;
display: inline-flex;
align-items: center;
gap: 4px;
&::before {
content: '';
width: 6px;
height: 6px;
border-radius: 50%;
background: #10b981;
}
}
.detail-btn {
background: #1e6fff;
border: none;
color: #fff;
font-size: 12px;
cursor: pointer;
display: flex;
align-items: center;
gap: 4px;
padding: 6px 12px;
border-radius: 4px;
transition: background 0.2s;
&:hover {
background: #0d5ae0;
}
i {
font-size: 12px;
transition: transform 0.2s;
}
&:hover i {
transform: translateX(2px);
}
}
}
}
.empty-state {
text-align: center;
padding: 60px 20px;
.empty-icon {
font-size: 48px;
margin-bottom: 16px;
color: #a0aec0;
}
.empty-text {
color: #999;
font-size: 14px;
margin: 0 0 6px;
}
span {
color: #b0b8c4;
font-size: 12px;
}
}
}
</style>

View File

@ -22,212 +22,281 @@
</button>
</header>
<!-- 主体 -->
<!-- 主体可滚动 -->
<main class="dialog-body">
<el-form ref="form" :model="formData" :rules="rules" label-position="top" class="opc-form">
<!-- 第一部分企业基本信息 -->
<section class="form-section">
<h3 class="section-title">
<span class="section-num">1</span>
企业基本信息
</h3>
<div class="grid-2">
<el-form-item label="企业名称" prop="company_name">
<el-input
v-model="formData.company_name"
placeholder="请输入企业名称"
maxlength="100"
/>
</el-form-item>
<el-form-item label="统一社会信用代码">
<el-input
v-model="formData.credit_code"
placeholder="请输入统一社会信用代码"
maxlength="18"
/>
</el-form-item>
<el-form-item label="成立时间">
<el-date-picker
v-model="formData.est_date"
type="date"
placeholder="选择日期"
value-format="yyyy-MM-dd"
class="full-width"
/>
</el-form-item>
<el-form-item label="从业人数(人)">
<el-input
v-model.number="formData.employee_count"
type="number"
placeholder="请输入从业人数"
min="1"
/>
<p class="field-tip">以最近一个月实际缴纳社保为准</p>
</el-form-item>
<el-form-item label="企业性质" class="col-span-2">
<div class="checkbox-group">
<label
v-for="item in companyTypeOptions"
:key="item"
class="checkbox-label"
:class="{ active: formData.company_type.includes(item) }"
>
<input
type="checkbox"
:value="item"
v-model="formData.company_type"
/>
<span>{{ item }}</span>
</label>
</div>
</el-form-item>
<el-form-item label="所属细分行业" class="col-span-2">
<el-input
v-model="formData.industry"
placeholder="请输入所属细分行业"
maxlength="100"
/>
</el-form-item>
<el-form-item label="注册地址">
<el-input
v-model="formData.reg_address"
placeholder="请输入注册地址"
maxlength="200"
/>
</el-form-item>
<el-form-item label="办公地址">
<el-input
v-model="formData.office_address"
placeholder="请输入办公地址"
maxlength="200"
/>
</el-form-item>
<el-form-item label="企业简介不超过1000字" class="col-span-2">
<el-input
v-model="formData.company_intro"
type="textarea"
:rows="4"
maxlength="1000"
show-word-limit
placeholder="请简要介绍企业主营业务、发展历程、核心优势等"
/>
</el-form-item>
</div>
</section>
<!-- 第二部分创始人信息 -->
<section class="form-section">
<h3 class="section-title">
<span class="section-num">2</span>
创始人信息
</h3>
<div class="grid-2">
<el-form-item label="单一创始人姓名" prop="founder_name">
<el-input
v-model="formData.founder_name"
placeholder="请输入创始人姓名"
maxlength="50"
/>
</el-form-item>
<el-form-item label="经股权穿透后合计持股比例(%">
<el-input
v-model.number="formData.shareholding_ratio"
type="number"
placeholder="请输入持股比例"
min="0"
max="100"
/>
</el-form-item>
<el-form-item label="联系电话" prop="founder_phone">
<el-input
v-model="formData.founder_phone"
placeholder="请输入联系电话"
maxlength="20"
/>
</el-form-item>
<el-form-item label="创始人在企业的技术创新、战略决策和主要业务执行中发挥主导作用情况" class="col-span-2">
<el-input
v-model="formData.founder_role"
type="textarea"
:rows="3"
placeholder="请说明创始人在企业技术创新、战略决策和主要业务执行中发挥的主导作用"
maxlength="500"
/>
</el-form-item>
<el-form-item label="上传相关证明文件(可选)" class="col-span-2">
<div class="file-upload-area">
<label class="upload-btn">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M15.172 7l-6.586 6.586a2 2 0 102.828 2.828l6.414-6.586a4 4 0 00-5.656-5.656l-6.415 6.585a6 6 0 108.486 8.486L20.5 13"/>
</svg>
<span>选择文件</span>
<input
type="file"
class="hidden"
accept=".pdf,.doc,.docx,.jpg,.jpeg,.png"
@change="handleFileChange($event, 'founder_file_list')"
/>
</label>
<div class="file-list">
<div
v-for="(file, index) in formData.founder_file_list"
:key="index"
class="file-item"
>
<span class="file-name">{{ file.name }}</span>
<button type="button" class="file-remove" @click="removeFile(index, 'founder_file_list')">×</button>
</div>
<!-- 第一部分企业基本信息 -->
<section class="form-section">
<h3 class="section-title">
<span class="section-num">1</span>
企业基本信息
</h3>
<!-- 企业名称一行 -->
<div class="field-row grid-2">
<div class="field-item">
<label class="field-label">企业名称 <span class="required">*</span></label>
<el-input
v-model="formData.company_name"
placeholder="请输入企业名称"
maxlength="100"
@blur="validateField('company_name')"
/>
<p v-if="errors.company_name" class="field-error">{{ errors.company_name }}</p>
</div>
<div class="field-item">
<label class="field-label">统一社会信用代码<span class="required">*</span></label>
<el-input
v-model="formData.credit_code"
placeholder="请输入统一社会信用代码"
maxlength="100"
@blur="validateField('credit_code')"
/>
<p v-if="errors.credit_code" class="field-error">{{ errors.credit_code }}</p>
</div>
</div>
<!-- 成立时间 / 从业人数一行 -->
<div class="field-row grid-2">
<div class="field-item">
<label class="field-label">成立时间</label>
<el-date-picker
v-model="formData.est_date"
type="date"
placeholder="选择日期"
value-format="yyyy-MM-dd"
class="full-width"
/>
</div>
<div class="field-item">
<label class="field-label">从业人数</label>
<el-input
v-model.number="formData.employee_count"
type="number"
placeholder="请输入从业人数"
min="1"
/>
<p class="field-tip">以最近一个月实际缴纳社保为准</p>
</div>
</div>
<!-- 企业性质一行 -->
<div class="field-row">
<div class="field-item">
<label class="field-label">企业性质</label>
<div class="checkbox-group">
<label
v-for="item in companyTypeOptions"
:key="item"
class="checkbox-label"
:class="{ active: formData.company_type.includes(item) }"
>
<input
type="checkbox"
:value="item"
v-model="formData.company_type"
/>
<span>{{ item }}</span>
</label>
</div>
</div>
</div>
<!-- 所属细分行业 / 注册地址一行 -->
<div class="field-row grid-2">
<div class="field-item">
<label class="field-label">所属细分行业</label>
<el-input
v-model="formData.industry"
placeholder="请输入所属细分行业"
maxlength="100"
/>
</div>
<div class="field-item">
<label class="field-label">注册地址</label>
<el-input
v-model="formData.reg_address"
placeholder="请输入注册地址"
maxlength="200"
/>
</div>
</div>
<!-- 办公地址一行 -->
<div class="field-row">
<div class="field-item">
<label class="field-label">办公地址</label>
<el-input
v-model="formData.office_address"
placeholder="请输入办公地址"
maxlength="200"
/>
</div>
</div>
<!-- 企业简介一行 -->
<div class="field-row">
<div class="field-item">
<label class="field-label">企业简介不超过1000字</label>
<el-input
v-model="formData.company_intro"
type="textarea"
:rows="4"
maxlength="1000"
show-word-limit
placeholder="请简要介绍企业主营业务、发展历程、核心优势等"
/>
</div>
</div>
</section>
<!-- 第二部分创始人信息 -->
<section class="form-section">
<h3 class="section-title">
<span class="section-num">2</span>
创始人信息
</h3>
<!-- 单一创始人姓名 / 持股比例一行 -->
<div class="field-row grid-2">
<div class="field-item">
<label class="field-label">单一创始人姓名 <span class="required">*</span></label>
<el-input
v-model="formData.founder_name"
placeholder="请输入创始人姓名"
maxlength="50"
@blur="validateField('founder_name')"
/>
<p v-if="errors.founder_name" class="field-error">{{ errors.founder_name }}</p>
</div>
<div class="field-item">
<label class="field-label">经股权穿透后合计持股比例%</label>
<el-input
v-model.number="formData.shareholding_ratio"
type="number"
placeholder="请输入持股比例"
min="0"
max="100"
/>
</div>
</div>
<!-- 联系电话一行 -->
<div class="field-row">
<div class="field-item">
<label class="field-label">联系电话 <span class="required">*</span></label>
<el-input
v-model="formData.founder_phone"
placeholder="请输入联系电话"
maxlength="20"
@blur="validateField('founder_phone')"
/>
<p v-if="errors.founder_phone" class="field-error">{{ errors.founder_phone }}</p>
</div>
</div>
<!-- 创始人作用情况一行 -->
<div class="field-row">
<div class="field-item">
<label class="field-label">创始人在企业的技术创新战略决策和主要业务执行中发挥主导作用情况</label>
<el-input
v-model="formData.founder_role"
type="textarea"
:rows="3"
placeholder="请说明创始人在企业技术创新、战略决策和主要业务执行中发挥的主导作用"
maxlength="500"
/>
</div>
</div>
<!-- 上传证明文件一行 -->
<div class="field-row">
<div class="field-item">
<label class="field-label">上传相关证明文件可另附文件</label>
<div class="file-upload-area">
<label class="upload-btn">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M15.172 7l-6.586 6.586a2 2 0 102.828 2.828l6.414-6.586a4 4 0 00-5.656-5.656l-6.415 6.585a6 6 0 108.486 8.486L20.5 13"/>
</svg>
<span>选择文件</span>
<input
type="file"
class="hidden"
accept=".pdf,.doc,.docx,.jpg,.jpeg,.png"
@change="handleFileChange($event, 'founder_file_list')"
/>
</label>
<div class="file-list">
<div
v-for="(file, index) in formData.founder_file_list"
:key="index"
class="file-item"
>
<span class="file-name">{{ file.name }}</span>
<button type="button" class="file-remove" @click="removeFile(index, 'founder_file_list')">×</button>
</div>
</div>
</el-form-item>
<el-form-item label="核心技术情况" class="col-span-2">
<el-input
v-model="formData.core_tech"
type="textarea"
:rows="3"
placeholder="以人工智能技术作为核心生产工具与关键驱动力利用大模型、智能体、AI开发工具等完成核心产品开发"
maxlength="500"
/>
</el-form-item>
</div>
</div>
</section>
</div>
<!-- 第三部分联系人信息 -->
<section class="form-section">
<h3 class="section-title">
<span class="section-num">3</span>
联系人信息
</h3>
<div class="grid-3">
<el-form-item label="联系人姓名" prop="contact_name">
<el-input
v-model="formData.contact_name"
placeholder="请输入联系人姓名"
maxlength="50"
/>
</el-form-item>
<el-form-item label="职务">
<el-input
v-model="formData.job_title"
placeholder="请输入职务"
maxlength="50"
/>
</el-form-item>
<el-form-item label="联系电话" prop="contact_phone">
<el-input
v-model="formData.contact_phone"
placeholder="请输入联系电话"
maxlength="20"
/>
</el-form-item>
<!-- 核心技术情况一行 -->
<div class="field-row">
<div class="field-item">
<label class="field-label">核心技术情况</label>
<el-input
v-model="formData.core_tech"
type="textarea"
:rows="3"
placeholder="以人工智能技术作为核心生产工具与关键驱动力利用大模型、智能体、AI开发工具等完成核心产品开发"
maxlength="500"
/>
</div>
</section>
</el-form>
</div>
</section>
<!-- 第三部分联系人信息 -->
<section class="form-section">
<h3 class="section-title">
<span class="section-num">3</span>
联系人信息
</h3>
<!-- 联系人姓名 / 职务 / 联系电话一行三列 -->
<div class="field-row grid-3">
<div class="field-item">
<label class="field-label">联系人姓名 <span class="required">*</span></label>
<el-input
v-model="formData.contact_name"
placeholder="请输入联系人姓名"
maxlength="50"
@blur="validateField('contact_name')"
/>
<p v-if="errors.contact_name" class="field-error">{{ errors.contact_name }}</p>
</div>
<div class="field-item">
<label class="field-label">职务</label>
<el-input
v-model="formData.job_title"
placeholder="请输入职务"
maxlength="50"
/>
</div>
<div class="field-item">
<label class="field-label">联系电话 <span class="required">*</span></label>
<el-input
v-model="formData.contact_phone"
placeholder="请输入联系电话"
maxlength="20"
@blur="validateField('contact_phone')"
/>
<p v-if="errors.contact_phone" class="field-error">{{ errors.contact_phone }}</p>
</div>
</div>
</section>
</main>
<!-- 底部 -->
<footer class="dialog-footer">
<el-button type="default" @click="saveDraft">保存草稿</el-button>
<el-button type="default" @click="handleClose">取消</el-button>
<el-button type="primary" :loading="submitting" @click="submitForm">提交申请</el-button>
</footer>
@ -246,18 +315,22 @@ props: {
}
},
data() {
const validatePhone = (rule, value, callback) => {
if (!value) {
callback(new Error('请输入联系电话'))
} else if (!/^1[3-9]\d{9}$/.test(value)) {
callback(new Error('请输入正确的手机号'))
} else {
callback()
}
const validatePhone = (value) => {
if (!value) return '请输入联系电话'
if (!/^1[3-9]\d{9}$/.test(value)) return '请输入正确的手机号'
return null
}
const validateCreditCode = (value) => {
if (!value) return '请输入统一社会信用代码'
const trimmed = String(value).trim()
// 18
if (!/^[0-9A-Z]{18}$/.test(trimmed)) return '请输入正确的统一社会信用代码18位数字或大写字母'
return null
}
return {
submitting: false,
companyTypeOptions: ['国有企业', '国有控股企业', '私营企业', '外资企业', '合资企业', '个体工商户', '其他'],
errors: {},
formData: {
company_name: '',
credit_code: '',
@ -277,13 +350,6 @@ data() {
contact_name: '',
job_title: '',
contact_phone: ''
},
rules: {
company_name: [{ required: true, message: '请输入企业名称', trigger: 'blur' }],
founder_name: [{ required: true, message: '请输入创始人姓名', trigger: 'blur' }],
founder_phone: [{ required: true, validator: validatePhone, trigger: 'blur' }],
contact_name: [{ required: true, message: '请输入联系人姓名', trigger: 'blur' }],
contact_phone: [{ required: true, validator: validatePhone, trigger: 'blur' }]
}
}
},
@ -301,6 +367,7 @@ watch: {
visible(val) {
if (val) {
this.loadDraft()
this.errors = {}
}
}
},
@ -334,22 +401,52 @@ methods: {
// ignore
}
},
validateField(field) {
const value = this.formData[field]
let msg = null
switch (field) {
case 'company_name':
case 'founder_name':
case 'contact_name':
if (!value) msg = '该项为必填项'
break
case 'credit_code':
msg = validateCreditCode(value)
break
case 'founder_phone':
case 'contact_phone':
msg = validatePhone(value)
break
}
if (msg) {
this.$set(this.errors, field, msg)
} else {
this.$delete(this.errors, field)
}
},
validateAll() {
['company_name', 'credit_code', 'founder_name', 'founder_phone', 'contact_name', 'contact_phone'].forEach(f => this.validateField(f))
return Object.keys(this.errors).length === 0
},
submitForm() {
this.$refs.form.validate(async valid => {
if (!valid) return
this.submitting = true
try {
// TODO:
console.log('提交数据:', this.formData)
this.$message.success('提交成功')
localStorage.removeItem('opc_application_draft')
if (!this.validateAll()) {
this.$message.error('请填写必填项')
return
}
this.submitting = true
try {
// TODO:
console.log('提交数据:', this.formData)
this.$message.success('提交成功')
localStorage.removeItem('opc_application_draft')
setTimeout(() => {
this.handleClose()
} catch (e) {
this.$message.error('提交失败,请重试')
} finally {
this.submitting = false
}
})
}, 800)
} catch (e) {
this.$message.error('提交失败,请重试')
} finally {
this.submitting = false
}
}
}
}

View File

@ -126,47 +126,47 @@ export default {
title: '北京市正式印发《支持人工智能OPC创新发展行动方案》试行',
desc: '北京市经济和信息化局正式印发《支持人工智能OPC创新发展行动方案》试行从培育孵化、算力支撑、场景开放、融资渠道、人才引进五大维度系统构建OPC创业支持体系。',
content: `
<p style="color:#374151;font-size:0.875rem;line-height:1.9;margin-bottom:0.75rem;">
<p style="color:#374151;line-height:1.9;">
为落实国家"人工智能+"战略构建活跃开放的人工智能创新创业生态支持青年人才创新创业助力超级经济个体OPC快速成长近日北京市经济和信息化局正式印发<strong style="color:#111827;">支持人工智能OPC创新发展行动方案试行</strong>方案围绕支持创办OPC企业建设OPC社区发放"全栈资源包"加强融资增信赋能强化赛事培优赋能举办全球OPC共创节深化合规引导赋能支持高校设立OPC微专业八大重点领域出台8条支持举措
</p>
<p style="color:#374151;font-size:0.875rem;line-height:1.9;margin-bottom:0.75rem;">
<p style="color:#374151;line-height:1.9;">
<strong style="color:#111827;">北京市经济和信息化局关于印发支持人工智能OPC创新发展行动方案试行的通知</strong>
</p>
<p style="color:#374151;font-size:0.875rem;line-height:1.9;margin-bottom:0.75rem;">各区中小企业主管部门各有关单位</p>
<p style="color:#374151;font-size:0.875rem;line-height:1.9;margin-bottom:0.75rem;">现将支持人工智能OPC创新发展行动方案试行印发给你们请结合实际认真贯彻落实</p>
<p style="color:#374151;font-size:0.875rem;line-height:1.9;margin-bottom:0.75rem;">北京市经济和信息化局</p>
<p style="color:#374151;font-size:0.875rem;line-height:1.9;margin-bottom:0.75rem;">2026年6月17日</p>
<p style="color:#374151;font-size:0.875rem;line-height:1.9;margin-bottom:0.75rem;">
<p style="color:#374151;line-height:1.9;">各区中小企业主管部门各有关单位</p>
<p style="color:#374151;line-height:1.9;">现将支持人工智能OPC创新发展行动方案试行印发给你们请结合实际认真贯彻落实</p>
<p style="color:#374151;line-height:1.9;">北京市经济和信息化局</p>
<p style="color:#374151;line-height:1.9;">2026年6月17日</p>
<p style="color:#374151;line-height:1.9;">
<strong style="color:#111827;">支持人工智能OPC创新发展行动方案试行</strong>
</p>
<p style="color:#374151;font-size:0.875rem;line-height:1.9;margin-bottom:0.75rem;">
<p style="color:#374151;line-height:1.9;">
为深入贯彻落实国家"人工智能+"战略部署加快构建活跃开放的人工智能创新创业生态支持青年人才创新创业培育一批AI驱动小而精专而强的创新主体助力更多超级经济个体OPC快速成长壮大本市中小企业科技创新力量制定本行动方案
</p>
<p style="color:#374151;font-size:0.875rem;line-height:1.9;margin-bottom:0.75rem;">
<p style="color:#374151;line-height:1.9;">
<strong style="color:#111827;">支持创办智能体开发</strong>AIGC产品创制大模型微调AI行业落地应用等领域的OPC企业依托北京市中小企业公共服务平台打造"OPC开办服务专区"提供开办指引社区入驻政策辅导和订单对接等全链条服务联合高校产业园区龙头企业开展OPC创业"校园行""园区行""企业行"通过政策宣讲案例分享技术培训等鼓励各类科技人才创办OPC
</p>
<p style="color:#374151;font-size:0.875rem;line-height:1.9;margin-bottom:0.75rem;">
<p style="color:#374151;line-height:1.9;">
<strong style="color:#111827;">出台OPC成长社区建设指引</strong>支持社区自建词元Token服务平台或链接智算服务机构数字员工服务平台为OPC企业提供AI工具集高质量数据集优惠算力低成本办公空间创业服务包等配套服务对于服务成效突出的OPC社区最高给予200万元资金支持鼓励新一代信息技术企业依托存量技术人才与产业生态资源探索建设企业内部OPC社区
</p>
<p style="color:#374151;font-size:0.875rem;line-height:1.9;margin-bottom:0.75rem;">
<p style="color:#374151;line-height:1.9;">
<strong style="color:#111827;">通过OPC成长社区为入驻OPC企业发放"全栈资源包"</strong>包含Token券模型券算力券数据券等入驻企业可免费享受3个月的模型使用智能算力使用数据代采赠送等服务单个企业合计最高不超过10万元OPC成长社区可按季度申请兑付每个社区每年最高不超过1000万元对通过北京人工智能数据沙盒服务平台开展数据治理和模型应用的OPC企业可享受50%服务费减免
</p>
<p style="color:#374151;font-size:0.875rem;line-height:1.9;margin-bottom:0.75rem;">
<p style="color:#374151;line-height:1.9;">
<strong style="color:#111827;">依托北京市企业融资综合信用服务平台设立"OPC金融服务专区"</strong>提供担保增信融资撮合政策对接等服务联合金融机构开发适配OPC企业的专属信贷产品"OPC贷"综合运用Token消耗数据赛事获奖情况创始人征信报告自主知识产权与自研技术成果等内容为企业提供增信支持
</p>
<p style="color:#374151;font-size:0.875rem;line-height:1.9;margin-bottom:0.75rem;">
<p style="color:#374151;line-height:1.9;">
<strong style="color:#111827;">联合一批投资机构举办"创赢未来"OPC专场路演活动</strong>由OPC社区推荐OPC企业参赛针对参赛企业提供"创训营"综合赋能服务对路演通过的OPC项目最高给予1000万元资金支持依托"创客北京""京彩大创"设立OPC专项赛道对于优质项目最高给予50万元资金支持
</p>
<p style="color:#374151;font-size:0.875rem;line-height:1.9;margin-bottom:0.75rem;">
<p style="color:#374151;line-height:1.9;">
<strong style="color:#111827;">举办全球OPC共创节</strong>通过AI黑客松AI工作坊项目路演大咖分享成果发布等系列活动为OPC企业提供项目展示的国际舞台和资源对接平台打造连接开发者创作者企业与大众的创新生态支持符合条件OPC企业参加中小企业服务券服务商遴选依托服务券政策推动其产品在中小企业中落地应用
</p>
<p style="color:#374151;font-size:0.875rem;line-height:1.9;margin-bottom:0.75rem;">
<p style="color:#374151;line-height:1.9;">
<strong style="color:#111827;">编制OPC合规指引</strong>梳理财税管理知识产权算法备案跨境出海等领域的风险要点明确合规要求和操作规范联合专业服务机构开展"合规服务进社区"活动通过合规咨询实操指导推动合规服务深度对接提升OPC企业合规经营意识与风险防控能力
</p>
<p style="color:#374151;font-size:0.875rem;line-height:1.9;margin-bottom:0.75rem;">
<p style="color:#374151;line-height:1.9;">
<strong style="color:#111827;">支持高校依托学科特色设立OPC微专业</strong>聚焦"人工智能大模型工程应用OPC创业实践"构建"AI通识政策解读场景实战"课程体系推行校企"双师制"教学推动形成"学科建设—产业需求—人才培养"闭环育人体系打造校企政合作共建的实训基地鼓励OPC社区开办"夜校""加速营"等OPC创业培训
</p>
<p style="color:#374151;font-size:0.875rem;line-height:1.9;margin-bottom:0;">
<p style="color:#374151;line-height:1.9;margin-bottom:0;">
本方案自印发之日起试行由北京市经济和信息化局负责解释
</p>
`
@ -180,26 +180,26 @@ export default {
source: '石景山区人民政府',
location: '石景山区',
date: '2026年7月10日',
url: '',
url: 'https://www.bjsjs.gov.cn/ywdt/sjsdt/202607/t20260723_763460.shtml',
title: '石景山区关于支持OPC创业生态发展的若干措施',
desc: '石景山区出台专项措施支持OPC创业生态发展涵盖入驻补贴、算力支持、融资对接、人才保障等多项扶持政策打造OPC创业首选地。',
content: `
<p style="color:#374151;font-size:0.875rem;line-height:1.9;margin-bottom:0.75rem;">
<p style="color:#374151;line-height:1.9;">
石景山区人民政府正式出台关于支持OPC创业生态发展的若干措施围绕OPC企业入驻算力支撑融资渠道人才保障等关键环节推出多项专项扶持政策旨在将石景山区打造为北京OPC创业首选地
</p>
<p style="color:#374151;font-size:0.875rem;line-height:1.9;margin-bottom:0.75rem;">
<p style="color:#374151;line-height:1.9;">
<strong style="color:#111827;">办公空间支持</strong>新入驻 OPC 企业首年办公租金全免第二年减免50%第三年减免30%单家最高可节省租金支出约500万元符合条件的企业可优先入驻石景山区人工智能产业园享受"一事一议"专项支持
</p>
<p style="color:#374151;font-size:0.875rem;line-height:1.9;margin-bottom:0.75rem;">
<p style="color:#374151;line-height:1.9;">
<strong style="color:#111827;">算力补贴政策</strong>联合区内智算中心为OPC企业提供专项算力包单家最高补贴200万元/企业可享受不高于市场价的80%算力采购折扣同时可申请算力"先用后付"试点服务
</p>
<p style="color:#374151;font-size:0.875rem;line-height:1.9;margin-bottom:0.75rem;">
<p style="color:#374151;line-height:1.9;">
<strong style="color:#111827;">融资对接机制</strong>设立 OPC 创投联盟搭建"基金 + 直投"双轨融资通道区级产业发展基金优先跟投优质OPC项目单笔跟投最高5000万元定期举办OPC项目路演及资本对接会
</p>
<p style="color:#374151;font-size:0.875rem;line-height:1.9;margin-bottom:0.75rem;">
<p style="color:#374151;line-height:1.9;">
<strong style="color:#111827;">人才引进保障</strong>为OPC企业引进的高层次人才提供最高100万元安家补贴在住房子女入学医疗等方面给予优先保障设立"石景山OPC人才服务专线"提供一对一政策咨询服务
</p>
<p style="color:#374151;font-size:0.875rem;margin-bottom:0;">
<p style="color:#374151;margin-bottom:0;">
<strong style="color:#111827;">政务绿色通道</strong>开通 OPC 项目"绿色通道"实行专班专员全程服务企业注册资质审批政策申报等事项平均提速50%以上
</p>
`
@ -213,26 +213,26 @@ export default {
source: '紫东数智OPC社区',
location: '北京市',
date: '2026年7月14日',
url: '',
url: 'https://mp.weixin.qq.com/s/8QKyYCloB468Lw2An0nW-A',
title: '紫东数智OPC社区正式揭牌',
desc: '紫东数智OPC社区正式揭牌成立标志着北京OPC创业生态建设迈入新阶段。社区由中关村数智人工智能产业联盟与紫东太初联合打造致力于构建集科研创新、项目孵化、创业加速与产业转化于一体的新型生态社区。',
content: `
<p style="color:#374151;font-size:0.875rem;line-height:1.9;margin-bottom:0.75rem;">
<p style="color:#374151;line-height:1.9;">
紫东数智OPC社区正式揭牌成立标志着北京OPC创业生态建设迈入新阶段社区由中关村数智人工智能产业联盟与紫东太初联合打造致力于构建集科研创新项目孵化创业加速与产业转化于一体的新型生态社区
</p>
<p style="color:#374151;font-size:0.875rem;line-height:1.9;margin-bottom:0.75rem;">
<p style="color:#374151;line-height:1.9;">
<strong style="color:#111827;">孵化空间</strong>社区首期启用2万平方米孵化空间覆盖50+创业团队配备独立办公室共享工位及会议室满足OPC企业不同阶段的空间需求
</p>
<p style="color:#374151;font-size:0.875rem;line-height:1.9;margin-bottom:0.75rem;">
<p style="color:#374151;line-height:1.9;">
<strong style="color:#111827;">产学研合作</strong>联合清华北航北理工等高校共建OPC联合实验室围绕大模型应用智能体开发AI行业落地等方向开展联合技术攻关推动科研成果转化
</p>
<p style="color:#374151;font-size:0.875rem;line-height:1.9;margin-bottom:0.75rem;">
<p style="color:#374151;line-height:1.9;">
<strong style="color:#111827;">品牌活动</strong>每月举办AI沙龙项目路演产业对接等品牌活动邀请学术界产业界投资界嘉宾分享前沿洞见为OPC创业者搭建高质量交流平台
</p>
<p style="color:#374151;font-size:0.875rem;line-height:1.9;margin-bottom:0.75rem;">
<p style="color:#374151;line-height:1.9;">
<strong style="color:#111827;">公共服务</strong>配套算力数据模型"一站式"公共服务平台提供优惠算力调用高质量数据集获取主流大模型API接入等服务降低OPC企业创新门槛
</p>
<p style="color:#374151;font-size:0.875rem;margin-bottom:0;">
<p style="color:#374151;margin-bottom:0;">
<strong style="color:#111827;">发展目标</strong>2026年内计划孵化30个标杆性OPC创业项目培育5家以上估值超亿元的OPC头部企业形成具有全国影响力的OPC创新高地
</p>
`

Binary file not shown.

After

Width:  |  Height:  |  Size: 669 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 684 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 741 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 738 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 893 KiB

View File

Before

Width:  |  Height:  |  Size: 115 KiB

After

Width:  |  Height:  |  Size: 115 KiB

View File

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 83 KiB

View File

@ -1,135 +1,624 @@
<template>
<div class="container">
<!-- slogan -->
<div class="slogan">
<div class="title">
<span class="gradient-text">数智开物</span>
<span class="clip-text">opc公共服务平台</span>
<span class="desp">紫东数智OPC社区 × 数智开物OPC公共服务平台超级个体从这里启航</span>
</div>
<div class="MetricsDisplay">
<div class="page-wrapper">
<!-- 网格背景点 -->
<div class="bg-grid"></div>
<div class="item">
<div class="item-title">
3500<span></span>
</div>
<div class="item-details">
社区建筑面积
</div>
<!-- 浮动光球装饰 -->
<div class="orb orb-1"></div>
<div class="orb orb-2"></div>
<div class="orb orb-3"></div>
<div class="orb orb-4"></div>
<div class="container">
<!-- slogan -->
<div class="slogan">
<div class="title">
<span class="gradient-text">数智开物</span>
<span class="clip-text">OPC公共服务平台</span>
<span class="desp">紫东数智OPC社区 × 数智开物OPC公共服务平台超级个体从这里启航</span>
</div>
<div class="item">
<div class="item-title">
3500<span></span>
</div>
<div class="item-details">
社区建筑面积
</div>
</div>
<div class="item">
<div class="item-title">
3500<span></span>
</div>
<div class="item-details">
社区建筑面积
</div>
</div>
<div class="item">
<div class="item-title">
3500<span></span>
</div>
<div class="item-details">
社区建筑面积
<div class="metrics-display">
<div class="metric-card" v-for="(item, index) in metrics" :key="index">
<div class="card-num">
{{ item.value }}
<span class="card-unit" v-if="item.unit">{{ item.unit }}</span>
</div>
<div class="card-label">{{ item.label }}</div>
</div>
</div>
</div>
</div>
<!-- 优惠政策 -->
<div class="policies">
<!-- 优惠政策 -->
<section class="policies">
<div class="policies-inner">
<div class="policies-header">
<h2 class="policies-title">优惠政策</h2>
<p class="policies-subtitle">
北京市及石景山区双重政策加持从培育孵化算力支撑场景开放到融资人才全方位支持
</p>
</div>
<div class="policy-grid">
<div
class="policy-card glass-card"
v-for="policy in policies"
:key="policy.id"
>
<div class="policy-card-header">
<div class="policy-icon" :style="{ background: policy.iconGradient }">
<svg class="icon-svg" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" :d="policy.icon"></path>
</svg>
</div>
<h3 class="policy-name">{{ policy.name }}</h3>
</div>
<p class="policy-desc">{{ policy.desc }}</p>
<div class="policy-amount">
<span class="amount-num" :style="{ color: policy.amountColor }">{{ policy.amount }}</span>
<span class="amount-unit" :style="{ color: policy.amountColor }">{{ policy.unit }}</span>
</div>
<div v-if="policy.subAmount" class="policy-sub-amount">
<span class="amount-num sub" :style="{ color: policy.amountColor }">{{ policy.subAmount }}</span>
<span class="amount-unit sub" :style="{ color: policy.amountColor }">{{ policy.subUnit }}</span>
</div>
</div>
</div>
<div class="policy-footer">
<p class="footer-note">
= 北京市支持人工智能OPC创新发展行动方案试行
= 石景山区关于支持OPC创业生态发展的若干措施试行
按从优不重复原则予以支持
</p>
</div>
</div>
</section>
<!-- 紫东数智OPC社区介绍 -->
<div class="community-intro">
<div class="community-intro-container">
<!-- 标题 -->
<div class="community-intro-header">
<h2 class="community-intro-title">紫东数智OPC社区介绍</h2>
<p class="community-intro-subtitle">
紫东数智OPC社区由中关村数智人工智能产业联盟与紫东太初联合打造<br>
"超级个体创业新型生态载体与协作网络"为定位致力于构建集科研创新项目孵化创业加速与产业转化于一体的新型生态社区
</p>
</div>
<!-- 社区简介 -->
<div class="community-intro-brief glass-card">
<div class="community-intro-brief-inner">
<div class="community-intro-logos">
<div class="community-intro-logo-wrapper">
<img src="./images/zhongguancun.jpg" alt="中关村数智人工智能产业联盟" class="community-intro-logo">
</div>
<div class="community-intro-logo-wrapper">
<img src="./images/zidongtaichu.png" alt="紫东太初" class="community-intro-logo">
</div>
</div>
<div class="community-intro-brief-content">
<h3 class="community-intro-brief-title">社区定位</h3>
<p class="community-intro-brief-text">
"一人即一团队、一AI即一生态"为核心理念紧扣人工智能重塑科研研发与创业组织方式的趋势社区落地于北京市石景山区人工智能产业集聚区首期投入<strong class="community-intro-brief-highlight">3500平方米</strong>标准化办公空间可实现拎包入驻
</p>
</div>
</div>
</div>
<!-- 核心优势 -->
<div class="core-advantages">
<div class="core-advantages-header">
<h3 class="core-advantages-title">核心优势</h3>
<p class="core-advantages-subtitle">五大支撑体系全方位赋能创业</p>
</div>
<div class="core-advantages-grid">
<!-- 数智开物公共服务平台 -->
<div class="core-advantage-card glass-card">
<div class="core-advantage-image-wrapper">
<img src="./images/illustration-platform.jpeg" alt="数智开物平台" class="core-advantage-image">
</div>
<div class="core-advantage-content">
<div class="core-advantage-icon-title">
<div class="core-advantage-icon core-advantage-icon--blue">
<svg class="core-advantage-icon-svg" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M5 12h14M5 12a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v4a2 2 0 01-2 2M5 12a2 2 0 00-2 2v4a2 2 0 002 2h14a2 2 0 002-2v-4a2 2 0 00-2-2m-2-4h.01M17 16h.01"></path>
</svg>
</div>
<h4 class="core-advantage-name">数智开物公共服务平台</h4>
</div>
<p class="core-advantage-desc">普惠算力多模型接入AIGC创作工具打造低成本创业数字底座云枢底座整合H800/A100/昇腾算力TOKEN市集集成50+主流大模型API</p>
</div>
</div>
<!-- 国产技术底座 -->
<div class="core-advantage-card glass-card">
<div class="core-advantage-image-wrapper">
<img src="./images/illustration-tech.jpeg" alt="国产技术底座" class="core-advantage-image">
</div>
<div class="core-advantage-content">
<div class="core-advantage-icon-title">
<div class="core-advantage-icon core-advantage-icon--cyan">
<svg class="core-advantage-icon-svg" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"></path>
</svg>
</div>
<h4 class="core-advantage-name">国产技术底座</h4>
</div>
<p class="core-advantage-desc">依托紫东太初技术能力与品牌势能对接具身智能与科学智能领域前沿技术资源提供技术对接窗口与生态合作入口</p>
</div>
</div>
<!-- 联盟全域生态资源 -->
<div class="core-advantage-card glass-card">
<div class="core-advantage-image-wrapper">
<img src="./images/illustration-ecosystem.jpeg" alt="联盟生态资源" class="core-advantage-image">
</div>
<div class="core-advantage-content">
<div class="core-advantage-icon-title">
<div class="core-advantage-icon core-advantage-icon--violet">
<svg class="core-advantage-icon-svg" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"></path>
</svg>
</div>
<h4 class="core-advantage-name">联盟生态资源</h4>
</div>
<p class="core-advantage-desc">汇聚小米集团浪潮集团等百余家头部会员单位聘请多位院士组成专家智库搭建上下游合作桥梁与专业技术指导</p>
</div>
</div>
<!-- 全链条创业配套 -->
<div class="core-advantage-card glass-card">
<div class="core-advantage-image-wrapper">
<img src="./images/illustration-services.jpeg" alt="创业配套服务" class="core-advantage-image">
</div>
<div class="core-advantage-content">
<div class="core-advantage-icon-title">
<div class="core-advantage-icon core-advantage-icon--amber">
<svg class="core-advantage-icon-svg" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4"></path>
</svg>
</div>
<h4 class="core-advantage-name">创业配套服务</h4>
</div>
<p class="core-advantage-desc">提供企业注册地址托管服务以及记账报税知识产权保护政策申报等事务的服务资源全链条支持创业</p>
</div>
</div>
<!-- 供需对接 -->
<div class="core-advantage-card glass-card">
<div class="core-advantage-image-wrapper">
<img src="./images/illustration-supply.jpeg" alt="供需对接" class="core-advantage-image">
</div>
<div class="core-advantage-content">
<div class="core-advantage-icon-title">
<div class="core-advantage-icon core-advantage-icon--rose">
<svg class="core-advantage-icon-svg" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4"></path>
</svg>
</div>
<h4 class="core-advantage-name">供需对接</h4>
</div>
<p class="core-advantage-desc">支持企业发布技术需求与合作信息平台基于标签实现智能匹配推荐联盟依托会员单位资源对大型综合订单进行拆解细分并派发助力入驻企业拓展业务渠道</p>
</div>
</div>
</div>
</div>
<!-- 服务内容 -->
<div class="service-content">
<div class="service-content-header">
<h3 class="service-content-title">服务内容</h3>
<p class="service-content-subtitle">围绕资源共享学习成长与协同创新三大维度构建服务体系</p>
</div>
<div class="service-content-grid">
<!-- 资源共享 -->
<div class="service-card glass-card">
<div class="service-card-header">
<div class="service-card-icon service-card-icon--blue">
<svg class="service-card-icon-svg" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M8 7v8a2 2 0 002 2h6M8 7V5a2 2 0 012-2h4.586a1 1 0 01.707.293l4.414 4.414a1 1 0 01.293.707V15a2 2 0 01-2 2h-2M8 7H6a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2v-2"></path>
</svg>
</div>
<h4 class="service-card-title">资源共享</h4>
</div>
<ul class="service-card-list">
<li class="service-card-list-item">
<span class="service-card-list-dot service-card-list-dot--blue"></span>
<span>提供办公载体空间与创新工位</span>
</li>
<li class="service-card-list-item">
<span class="service-card-list-dot service-card-list-dot--blue"></span>
<span>集成数智开物公共服务平台紫东太初多模态大模型及ScienceClaw科学智能平台使用权限</span>
</li>
<li class="service-card-list-item">
<span class="service-card-list-dot service-card-list-dot--blue"></span>
<span>搭建经验交流技能交易与项目协作置换机制</span>
</li>
</ul>
</div>
<!-- 学习成长 -->
<div class="service-card glass-card">
<div class="service-card-header">
<div class="service-card-icon service-card-icon--emerald">
<svg class="service-card-icon-svg" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"></path>
</svg>
</div>
<h4 class="service-card-title">学习成长</h4>
</div>
<ul class="service-card-list">
<li class="service-card-list-item">
<span class="service-card-list-dot service-card-list-dot--emerald"></span>
<span>依托联盟专家智库打通上下游产业链</span>
</li>
<li class="service-card-list-item">
<span class="service-card-list-dot service-card-list-dot--emerald"></span>
<span>提供前沿技术指导与商业合作对接</span>
</li>
<li class="service-card-list-item">
<span class="service-card-list-dot service-card-list-dot--emerald"></span>
<span>定期举办AI技术前沿沙龙开设OPC创业课程</span>
</li>
<li class="service-card-list-item">
<span class="service-card-list-dot service-card-list-dot--emerald"></span>
<span>配备创业与技术双导师指导</span>
</li>
</ul>
</div>
<!-- 协同创新 -->
<div class="service-card glass-card">
<div class="service-card-header">
<div class="service-card-icon service-card-icon--violet">
<svg class="service-card-icon-svg" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"></path>
</svg>
</div>
<h4 class="service-card-title">协同创新</h4>
</div>
<ul class="service-card-list">
<li class="service-card-list-item">
<span class="service-card-list-dot service-card-list-dot--violet"></span>
<span>协助入驻团队申报产业政策与投融资对接</span>
</li>
<li class="service-card-list-item">
<span class="service-card-list-dot service-card-list-dot--violet"></span>
<span>对优质项目给予平台重点扶持</span>
</li>
<li class="service-card-list-item">
<span class="service-card-list-dot service-card-list-dot--violet"></span>
<span>已成功举办WAIC FT OPC大赛</span>
</li>
<li class="service-card-list-item">
<span class="service-card-list-dot service-card-list-dot--violet"></span>
<span>持续策划OPC专题赛事提供赛事奖金与资源支持</span>
</li>
</ul>
</div>
</div>
</div>
<!-- 招募信息 -->
<div class="recruitment-banner">
<div class="recruitment-banner-inner">
<div class="recruitment-banner-content">
<h3 class="recruitment-banner-title">入驻招募</h3>
<p class="recruitment-banner-text">
社区面向人工智能领域个体创新者及初创小微团队开展招募优先方向为<strong class="recruitment-banner-highlight">具身智能</strong><strong class="recruitment-banner-highlight">AI4S科研</strong><strong class="recruitment-banner-highlight">AIGC文娱</strong>等领域
</p>
<div class="recruitment-banner-tags">
<div class="recruitment-tag recruitment-tag--blue">
<svg class="recruitment-tag-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"></path>
</svg>
<span class="recruitment-tag-text">具身智能</span>
</div>
<div class="recruitment-tag recruitment-tag--emerald">
<svg class="recruitment-tag-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19.428 15.428a2 2 0 00-1.022-.547l-2.387-.477a6 6 0 00-3.86.517l-.318.158a6 6 0 01-3.86.517L6.05 15.21a2 2 0 00-1.806.547M8 4h8l-1 1v5.172a2 2 0 00.586 1.414l5 5c1.26 1.26.367 3.414-1.415 3.414H4.828c-1.782 0-2.674-2.154-1.414-3.414l5-5A2 2 0 009 10.172V5L8 4z"></path>
</svg>
<span class="recruitment-tag-text">AI4S科研</span>
</div>
<div class="recruitment-tag recruitment-tag--violet">
<svg class="recruitment-tag-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 4v16M17 4v16M3 8h4m10 0h4M3 12h18M3 16h4m10 0h4M4 20h16a1 1 0 001-1V5a1 1 0 00-1-1H4a1 1 0 00-1 1v14a1 1 0 001 1z"></path>
</svg>
<span class="recruitment-tag-text">AIGC文娱</span>
</div>
</div>
</div>
<div class="recruitment-banner-actions">
<button @click="openEntryRequirements" class="recruitment-btn recruitment-btn--blue">
<span>了解入驻要求</span>
</button>
<button @click="openEntryFormModal" class="recruitment-btn recruitment-btn--violet">
<span>入驻申请</span>
<svg class="recruitment-btn-arrow" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
</svg>
</button>
</div>
</div>
</div>
</div>
<!-- 背景装饰 -->
<div class="community-intro-bg">
<div class="community-intro-bg-orb community-intro-bg-orb--blue"></div>
<div class="community-intro-bg-orb community-intro-bg-orb--violet"></div>
</div>
<!-- 入驻要求弹窗 -->
<transition name="modal-fade">
<div
v-if="showEntryRequirements"
class="entry-requirements-overlay"
@click.self="closeEntryRequirements"
>
<div class="entry-requirements-modal">
<!-- 头部 -->
<div class="entry-requirements-header">
<div class="entry-requirements-header-inner">
<h2 class="entry-requirements-title">OPC企业入驻要求</h2>
</div>
<button @click="closeEntryRequirements" class="entry-requirements-close">
<svg class="entry-requirements-close-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
</svg>
</button>
</div>
<!-- 内容 -->
<div class="entry-requirements-body">
<!-- 入驻条件 -->
<h3 class="entry-requirements-section-title">
<span class="entry-requirements-section-indicator entry-requirements-section-indicator--blue"></span>
入驻条件
</h3>
<div class="entry-requirements-list">
<div class="entry-requirements-item">
<span class="entry-requirements-item-num">1</span>
<p class="entry-requirements-item-text">在京企业近三年无严重失信记录</p>
</div>
<div class="entry-requirements-item">
<span class="entry-requirements-item-num">2</span>
<p class="entry-requirements-item-text">员工总数原则上不超过10人</p>
</div>
<div class="entry-requirements-item">
<span class="entry-requirements-item-num">3</span>
<p class="entry-requirements-item-text">营业执照经营范围包含"人工智能"字样</p>
</div>
<div class="entry-requirements-item">
<span class="entry-requirements-item-num">4</span>
<p class="entry-requirements-item-text">单一创始人在企业的技术创新战略决策和主要业务执行中发挥主导作用经股权穿透后单一创始人合计持股比例超过50%</p>
</div>
<div class="entry-requirements-item">
<span class="entry-requirements-item-num">5</span>
<p class="entry-requirements-item-text">以人工智能技术作为核心生产工具与关键驱动力利用大模型智能体AI开发工具等完成核心产品开发</p>
</div>
</div>
<!-- 入驻需提交信息 -->
<h3 class="entry-requirements-section-title">
<span class="entry-requirements-section-indicator entry-requirements-section-indicator--emerald"></span>
入驻需提交信息
</h3>
<div class="entry-requirements-grid">
<div class="entry-requirements-grid-item">
<div class="entry-requirements-grid-label">基本信息</div>
<div class="entry-requirements-grid-value">企业名称统一社会信用代码成立时间</div>
</div>
<div class="entry-requirements-grid-item">
<div class="entry-requirements-grid-label">企业规模</div>
<div class="entry-requirements-grid-value">从业人数企业性质所属细分行业</div>
</div>
<div class="entry-requirements-grid-item">
<div class="entry-requirements-grid-label">企业地址</div>
<div class="entry-requirements-grid-value">注册地址办公地址</div>
</div>
<div class="entry-requirements-grid-item">
<div class="entry-requirements-grid-label">企业简介</div>
<div class="entry-requirements-grid-value">不超过1000字</div>
</div>
<div class="entry-requirements-grid-item">
<div class="entry-requirements-grid-label">创始人信息</div>
<div class="entry-requirements-grid-value">姓名持股比例联系电话</div>
</div>
<div class="entry-requirements-grid-item">
<div class="entry-requirements-grid-label">核心技术情况</div>
<div class="entry-requirements-grid-value">AI技术应用核心产品说明</div>
</div>
</div>
<!-- 联系方式 -->
<div class="entry-requirements-contact">
<div class="entry-requirements-contact-header">
<svg class="entry-requirements-contact-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
<span class="entry-requirements-contact-title">联系方式</span>
</div>
<div class="entry-requirements-contact-info">
<p>电话010-59227146</p>
<p>邮箱huqiao@bjzai.org.cn备注OPC社区入驻申请+项目名称+负责人姓名</p>
<p>工作时间工作日 9:00-12:0013:30-18:00</p>
</div>
</div>
</div>
</div>
</div>
</transition>
<!-- 入驻申请弹窗 -->
<OpcJoinDialog
:visible.sync="showJoinDialog"
@close="handleJoinDialogClose"
/>
</div>
</div>
</div>
</template>
<script>
import OpcJoinDialog from './OpcJoinDialog.vue'
export default {
name: 'ComponentName',
name: 'NcmatchIndex',
components: {
OpcJoinDialog
},
data() {
return {
//
showJoinDialog: false,
//
showEntryRequirements: false,
metrics: [
{ value: '3500', unit: '㎡', label: '社区建筑面积' },
{ value: '100', unit: '万', label: '最高商业化奖励' },
{ value: '200', unit: '万', label: '年度算力券支持' },
{ value: '5', unit: '大', label: '核心服务体系' },
],
policies: [
{
id: 1,
name: '创业启动资金【石】',
desc: '支持毕业五年内高校毕业生、在校师生、科研团队及科技人才创办OPC企业经认定给予一次性启动资金可申报"景贤人才"。',
amount: '10',
unit: '万元 / 启动扶持',
subAmount: '',
subUnit: '',
iconGradient: 'linear-gradient(135deg, #2563eb 0%, #3b82f6 100%)',
icon: 'M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z',
amountColor: '#2563eb'
},
{
id: 2,
name: '全栈资源包【市】',
desc: '入驻社区可申领Token、算力、数据、模型工具等补贴。',
amount: '10',
unit: '万元 / 单企业资源上限',
subAmount: '',
subUnit: '',
iconGradient: 'linear-gradient(135deg, #0891b2 0%, #06b6d4 100%)',
icon: 'M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10',
amountColor: '#0891b2'
},
{
id: 3,
name: '模工具与算力支持【石】',
desc: '鼓励使用智能体技术工具进行研发创新,发放词元或算力券,社区按季度申请兑付。',
amount: '200',
unit: '万元 / 年',
subAmount: '',
subUnit: '',
iconGradient: 'linear-gradient(135deg, #7c3aed 0%, #8b5cf6 100%)',
icon: 'M9 3v2m6-2v2M9 19v2m6-2v2M5 9H3m2 6H3m18-6h-2m2 6h-2M7 19h10a2 2 0 002-2V7a2 2 0 00-2-2H7a2 2 0 00-2 2v10a2 2 0 002 2zM9 9h6v6H9V9z',
amountColor: '#7c3aed'
},
{
id: 4,
name: '商业化突破奖励【石】',
desc: '形成自主核心成果并实现首次市场转化的OPC企业经评审给予一次性资金支持。',
amount: '100',
unit: '万元 / 首次转化',
subAmount: '',
subUnit: '',
iconGradient: 'linear-gradient(135deg, #d97706 0%, #f59e0b 100%)',
icon: 'M13 7h8m0 0v8m0-8l-8 8-4-4-6 6',
amountColor: '#d97706'
},
{
id: 5,
name: '赛事路演支持【市/石】',
desc: '市级"创赢未来"OPC专场路演、"创客北京""京彩大创"OPC专项赛道区级赛事获奖成果转化支持。',
amount: '1000',
unit: '万元 / 路演项目(北京市)',
subAmount: '50',
subUnit: '万元 / 赛事转化(石景山)',
iconGradient: 'linear-gradient(135deg, #dc2626 0%, #ef4444 100%)',
icon: 'M19 20H5a2 2 0 01-2-2V6a2 2 0 012-2h10a2 2 0 012 2v1m2 13a2 2 0 01-2-2V7m2 13a2 2 0 002-2V9a2 2 0 00-2-2h-2m-4-3H9M7 16h6M7 8h6v4H7V8z',
amountColor: '#dc2626'
},
{
id: 6,
name: '融资增信服务【市/石】',
desc: '市级"OPC金融服务专区"担保增信、专属信贷"OPC贷";区级普惠贷款与创业担保贷款贴息。',
amount: '50',
unit: '万元 / 年贴息上限(石景山)',
subAmount: '',
subUnit: '',
iconGradient: 'linear-gradient(135deg, #059669 0%, #10b981 100%)',
icon: 'M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z',
amountColor: '#059669'
},
{
id: 7,
name: '人才安居保障【石】',
desc: '为入驻社区创业人才提供免费周转住房,期满后享受租金优惠。',
amount: '3',
unit: '个月免费 + 3年优惠',
subAmount: '',
subUnit: '',
iconGradient: 'linear-gradient(135deg, #4f46e5 0%, #6366f1 100%)',
icon: 'M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6',
amountColor: '#4f46e5'
},
{
id: 8,
name: '政务服务保障【石】',
desc: 'OPC登记专窗实现"一站准入、一日办结"。',
amount: '1',
unit: '日办结',
subAmount: '',
subUnit: '',
iconGradient: 'linear-gradient(135deg, #0284c7 0%, #0ea5e9 100%)',
icon: 'M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-3 7h3m-3 4h3m-6-4h.01M9 16h.01',
amountColor: '#0284c7'
},
{
id: 9,
name: '合规与培训赋能【市】',
desc: '编制OPC合规指引财税、知识产权、算法备案、跨境出海支持高校设OPC微专业社区开办夜校与加速营。',
amount: '全链条合规',
unit: '+ 育人闭环',
subAmount: '',
subUnit: '',
iconGradient: 'linear-gradient(135deg, #be185d 0%, #ec4899 100%)',
icon: 'M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253',
amountColor: '#be185d'
}
]
};
},
computed: {
},
computed: {},
methods: {
//
openEntryRequirements() {
this.showEntryRequirements = true;
document.body.style.overflow = 'hidden';
},
//
closeEntryRequirements() {
this.showEntryRequirements = false;
document.body.style.overflow = '';
},
//
openEntryFormModal() {
this.showJoinDialog = true;
},
//
handleJoinDialogClose() {
this.showJoinDialog = false;
}
}
};
</script>
<style scoped lang="less">
.container {
width: 100%;
height: 100%;
}
.slogan {
width: 100%;
height: 100%;
padding: 176px 0;
.title {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding-bottom: 62px;
.gradient-text {
font-size: 72px;
font-weight: 800;
background: linear-gradient(135deg, #1e40af 0%, #2563eb 40%, #3b82f6 70%, #0ea5e9 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.clip-text{
font-size: 72px;
font-weight: 800;
background: linear-gradient(to right, rgb(147, 51, 234), rgb(37, 99, 235), rgb(6, 182, 212));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
margin-bottom: 32px;
}
.desp{
font-size: 20px;
color:rgb(75, 85, 99)
}
}
.MetricsDisplay {
display: flex;
justify-content: center;
gap: 80px;
.item {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.item-title{
font-size: 36px;
font-weight: 700;
span{
color: #2563EB;
}
}
.item-details{
font-size: 14px;
color: #6B7280;
}
}
}
}
</style>
@import url('./less/index.less');
</style>

View File

@ -1,24 +1,27 @@
// ==================== Dialog Shell ====================
::v-deep .opc-application-dialog {
margin: 0 auto !important;
width: 100% !important;
max-width: 900px;
// max-height: 85vh;
border-radius: 16px !important;
background: #ffffff;
border: 1px solid #dbeafe;
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
overflow: hidden;
display: flex;
background: transparent !important;
border: none !important;
box-shadow: none !important;
display: flex !important;
flex-direction: column;
max-height: 85vh !important;
top: 100px;
.el-dialog__header {
display: none;
}
.el-dialog__body {
flex: 1;
flex: 1 1 auto;
padding: 0;
overflow: hidden;
overflow: hidden !important;
display: flex;
flex-direction: column;
background: transparent !important;
min-height: 0;
}
}
@ -27,24 +30,29 @@
background: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(4px);
-webkit-backdrop-filter: blur(4px);
overflow: hidden;
}
// ==================== Layout Container ====================
.dialog-layout {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
background: #ffffff;
max-height: 85vh;
overflow: hidden;
background: #ffffff;
border-radius: 16px;
border: 1px solid #dbeafe;
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
}
// ==================== Header ====================
.dialog-header {
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: space-between;
padding: 20px 32px;
background: #ffffff;
border-bottom: 1px solid #f0f0f0;
.header-info {
@ -82,12 +90,16 @@
}
}
// ==================== Body (scrollable) ====================
.dialog-body {
flex: 1;
flex: 1 1 auto;
overflow-y: auto;
overflow-x: hidden;
padding: 24px 32px;
min-height: 0;
}
// ==================== Footer ====================
.dialog-footer {
flex-shrink: 0;
display: flex;
@ -117,11 +129,25 @@
border-radius: 8px;
font-size: 14px;
height: 40px;
padding: 0 20px;
border-color: #e5e7eb;
color: #6b7280;
background: #ffffff;
&:hover {
border-color: #d1d5db;
color: #374151;
}
}
}
// ==================== Form Section ====================
.form-section {
margin-bottom: 32px;
margin-bottom: 28px;
&:last-child {
margin-bottom: 0;
}
.section-title {
display: flex;
@ -143,36 +169,137 @@
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
}
}
.grid-2 {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 16px;
// ==================== Field Row核心一行就是一个 .field-row ====================
// 关键设计:每个"一行"就是一个独立 .field-row 容器
// - 单列:.field-row里面 1 个 .field-item 独占整行)
// - 两列:.field-row.grid-2里面 2 个 .field-item 自动等分两列)
// - 三列:.field-row.grid-3里面 3 个 .field-item 自动等分三列)
// 这样无论每行是 1、2、3 个字段,列宽都严格对齐
.field-row {
display: block;
margin-bottom: 16px;
.col-span-2 {
grid-column: 1 / -1;
&:last-child {
margin-bottom: 0;
}
}
.grid-3 {
.field-row.grid-2 {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 16px;
}
.full-width {
width: 100%;
.field-row.grid-3 {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 16px;
}
// ==================== Field Item ====================
.field-item {
display: block;
min-width: 0;
}
.field-label {
display: block;
font-size: 14px;
font-weight: 500;
color: #374151;
margin-bottom: 6px;
line-height: 1.4;
.required {
color: #ef4444;
margin-left: 2px;
}
}
.field-tip {
margin: 4px 0 0;
font-size: 12px;
color: #9ca3af;
line-height: 1.4;
}
.field-error {
margin: 4px 0 0;
font-size: 12px;
color: #ef4444;
line-height: 1.4;
}
.full-width {
width: 100%;
}
// ==================== Element UI Input Overrides ====================
::v-deep .el-input__inner,
::v-deep .el-textarea__inner {
border-radius: 8px;
border-color: #e5e7eb;
background: #f9fafb;
font-size: 14px;
color: #111827;
width: 100%;
box-sizing: border-box;
transition: border-color 0.15s, box-shadow 0.15s;
&::placeholder {
color: #9ca3af;
}
&:focus {
border-color: #2563eb;
background: #ffffff;
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);
outline: none;
}
}
::v-deep .el-input {
width: 100% !important;
display: block !important;
.el-input__inner {
height: 40px;
}
}
::v-deep .el-textarea {
width: 100% !important;
display: block !important;
}
::v-deep .el-textarea__inner {
resize: none;
padding: 10px 14px;
line-height: 1.5;
}
::v-deep .el-date-editor.el-input {
width: 100%;
.el-input__inner {
padding-right: 30px;
}
}
::v-deep .el-input-number {
width: 100% !important;
.el-input__inner {
text-align: left;
padding-left: 14px;
padding-right: 60px;
}
}
// ==================== Checkbox Group ====================
.checkbox-group {
display: flex;
flex-wrap: wrap;
@ -180,7 +307,7 @@
}
.checkbox-label {
display: flex;
display: inline-flex;
align-items: center;
gap: 6px;
padding: 6px 12px;
@ -209,6 +336,7 @@
}
}
// ==================== File Upload ====================
.file-upload-area {
display: flex;
flex-direction: column;
@ -274,75 +402,13 @@
}
}
::v-deep .opc-form {
.el-form-item {
margin-bottom: 0;
}
.el-form-item__label {
padding-bottom: 6px;
font-size: 14px;
font-weight: 500;
color: #374151;
line-height: 1.4;
}
.el-form-item__error {
position: static;
padding-top: 4px;
font-size: 12px;
}
.el-input__inner,
.el-textarea__inner {
border-radius: 8px;
border-color: #e5e7eb;
background: #f9fafb;
font-size: 14px;
color: #111827;
&::placeholder {
color: #9ca3af;
}
&:focus {
border-color: #2563eb;
background: #ffffff;
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);
}
}
.el-input {
.el-input__inner {
height: 40px;
}
}
.el-textarea__inner {
resize: none;
}
.el-checkbox__input.is-checked .el-checkbox__inner {
background-color: #2563eb;
border-color: #2563eb;
}
.el-checkbox__label {
color: #374151;
font-size: 14px;
}
}
// ==================== Responsive ====================
@media (max-width: 768px) {
.grid-2,
.grid-3 {
.field-row.grid-2,
.field-row.grid-3 {
grid-template-columns: 1fr;
}
.col-span-2 {
grid-column: 1;
}
.dialog-header {
padding: 16px 20px;
}
@ -353,10 +419,15 @@
.dialog-footer {
padding: 12px 16px;
gap: 8px;
}
::v-deep .opc-application-dialog {
margin: 16px auto !important;
max-height: calc(100vh - 32px);
max-height: calc(100vh - 32px) !important;
.el-dialog__body {
max-height: calc(100vh - 32px) !important;
}
}
}

View File

@ -454,8 +454,8 @@
}
.detail-content {
font-size: 14px;
line-height: 1.9;
font-size: 13px;
line-height: 1.85;
color: #374151;
p {

File diff suppressed because it is too large Load Diff

View File

@ -18,7 +18,7 @@
</div>
<!-- 园区图片 -->
<div class="hero-images">
<div class="hero-images">
<div class="image-card">
<div class="image-wrapper">
<img src="./images/opc-community-sign.jpeg" alt="紫东数智OPC社区">
@ -37,7 +37,7 @@
</div>
</div>
</div>
</section>
</section>
<!-- 入驻流程 -->
<section class="process-section">
@ -142,7 +142,7 @@
export default {
name: 'OpcOverview',
components: { OpcJoinDialog },
data() {
data() {
return {
showFormModal: false
}

View File

@ -0,0 +1,823 @@
<template>
<div class="supply-demand-wrapper">
<!-- 网格背景点 -->
<div class="bg-grid"></div>
<!-- 浮动光球装饰 -->
<div class="orb orb-1"></div>
<div class="orb orb-2"></div>
<div class="orb orb-3"></div>
<div class="orb orb-4"></div>
<!-- 供需广场主体 -->
<main class="supply-demand">
<div class="supply-demand-container">
<!-- 页面标题 -->
<div class="supply-demand-header">
<h1 class="supply-demand-title gradient-text">供需广场</h1>
<p class="supply-demand-subtitle">产业需求与能力精准对接助力资源高效匹配</p>
</div>
<!-- 简单六步 -->
<div class="process-flow">
<h2 class="process-flow-title">简单六步开启服务合作之旅</h2>
<div class="process-flow-steps">
<!-- 企业入驻 -->
<div class="process-step glass-card" @click="openEntryFormModal">
<div class="process-step-header">
<div class="process-step-icon process-step-icon--blue">
<svg class="process-step-icon-svg" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4"></path>
</svg>
</div>
<h3 class="process-step-name">企业入驻</h3>
</div>
<p class="process-step-desc">点击填写入驻申请</p>
</div>
<!-- 箭头 -->
<svg class="process-arrow" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
</svg>
<!-- 发布供需 -->
<div class="process-step glass-card">
<div class="process-step-header">
<div class="process-step-icon process-step-icon--cyan">
<svg class="process-step-icon-svg" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"></path>
</svg>
</div>
<h3 class="process-step-name">发布供需</h3>
</div>
<p class="process-step-desc">发布资源供给或业务需求信息</p>
</div>
<!-- 箭头 -->
<svg class="process-arrow" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
</svg>
<!-- 精准匹配 -->
<div class="process-step glass-card">
<div class="process-step-header">
<div class="process-step-icon process-step-icon--emerald">
<svg class="process-step-icon-svg" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M13 10V3L4 14h7v7l9-11h-7z"></path>
</svg>
</div>
<h3 class="process-step-name">精准匹配</h3>
</div>
<p class="process-step-desc">AI引擎智能推荐最优合作方</p>
</div>
<!-- 箭头 -->
<svg class="process-arrow" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
</svg>
<!-- 签约合作 -->
<div class="process-step glass-card">
<div class="process-step-header">
<div class="process-step-icon process-step-icon--teal">
<svg class="process-step-icon-svg" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"></path>
</svg>
</div>
<h3 class="process-step-name">签约合作</h3>
</div>
<p class="process-step-desc">线上签约安全高效达成合作</p>
</div>
<!-- 箭头 -->
<svg class="process-arrow" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
</svg>
<!-- 履约跟进 -->
<div class="process-step glass-card">
<div class="process-step-header">
<div class="process-step-icon process-step-icon--amber">
<svg class="process-step-icon-svg" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path>
</svg>
</div>
<h3 class="process-step-name">履约跟进</h3>
</div>
<p class="process-step-desc">全程跟踪项目执行进度</p>
</div>
<!-- 箭头 -->
<svg class="process-arrow" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
</svg>
<!-- 在线验收 -->
<div class="process-step glass-card">
<div class="process-step-header">
<div class="process-step-icon process-step-icon--purple">
<svg class="process-step-icon-svg" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
</div>
<h3 class="process-step-name">在线验收</h3>
</div>
<p class="process-step-desc">线上验收确保交付质量</p>
</div>
</div>
</div>
<!-- 筛选标签 -->
<div class="tab-nav">
<button
class="tab-nav-item"
:class="{ 'tab-nav-item--active': currentTab === 'all' }"
@click="switchTab('all')"
>全部</button>
<button
class="tab-nav-item"
:class="{ 'tab-nav-item--active': currentTab === 'demand' }"
@click="switchTab('demand')"
>需求发布</button>
<button
class="tab-nav-item"
:class="{ 'tab-nav-item--active': currentTab === 'supply' }"
@click="switchTab('supply')"
>能力供给</button>
<button
class="tab-nav-item"
:class="{ 'tab-nav-item--active': currentTab === 'signed' }"
@click="switchTab('signed')"
>签约项目</button>
</div>
<!-- 筛选侧边栏 + 卡片列表 -->
<div class="content-layout">
<!-- 左侧筛选面板 -->
<aside class="filter-sidebar">
<!-- 能力供给分类全部时只展示前3个 -->
<div v-show="currentTab === 'all' || currentTab === 'supply'" class="filter-group">
<h3 class="filter-group-title">
<span class="filter-group-badge filter-group-badge--blue"></span>
企业分类
</h3>
<div class="filter-buttons">
<button
class="filter-btn"
:class="{ 'filter-btn--active': activeSupplyFilter === category }"
@click="filterSupply(category)"
v-for="category in currentTab === 'all' ? supplyCategories.slice(0, 3) : supplyCategories"
:key="'s-' + category"
>{{ category }}</button>
</div>
</div>
<div v-show="currentTab === 'all' || currentTab === 'supply'" class="filter-divider"></div>
<!-- 需求发布分类 -->
<div v-show="currentTab === 'all' || currentTab === 'demand'" class="filter-group">
<h3 class="filter-group-title">
<span class="filter-group-badge filter-group-badge--cyan"></span>
需求分类
</h3>
<div class="filter-buttons">
<button
class="filter-btn"
:class="{ 'filter-btn--active': activeDemandFilter === category }"
@click="filterDemand(category)"
v-for="category in currentTab === 'all' ? demandCategories.slice(0, 3) : demandCategories"
:key="'d-' + category"
>{{ category }}</button>
</div>
</div>
<div v-show="currentTab === 'all' || currentTab === 'demand'" class="filter-divider"></div>
<!-- 签约项目分类 -->
<div v-show="currentTab === 'all' || currentTab === 'signed'" class="filter-group">
<h3 class="filter-group-title">
<span class="filter-group-badge filter-group-badge--emerald"></span>
签约分类
</h3>
<div class="filter-buttons">
<button
class="filter-btn"
:class="{ 'filter-btn--active': activeSignedFilter === category }"
@click="filterSigned(category)"
v-for="category in currentTab === 'all' ? signedCategories.slice(0, 3) : signedCategories"
:key="'g-' + category"
>{{ category }}</button>
</div>
</div>
</aside>
<!-- 卡片列表 -->
<div class="card-grid" id="item-list">
<!-- 空状态卡片 -->
<div v-if="filteredItems.length === 0" class="empty-state">
<svg class="empty-state-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4"></path>
</svg>
<p class="empty-state-text">暂无数据</p>
<p class="empty-state-hint">该分类下暂无相关信息</p>
</div>
</div>
</div>
</div>
</main>
<OpcJoinDialog :visible.sync="showJoinDialog" @close="handleJoinDialogClose" />
</div>
</template>
<script>
import OpcJoinDialog from './OpcJoinDialog.vue'
export default {
name: 'SupplyDemand',
components: {
OpcJoinDialog
},
data() {
return {
// 广
currentTab: 'all',
activeSupplyFilter: '全部',
activeDemandFilter: '全部',
activeSignedFilter: '全部',
supplyCategories: ['全部', 'AI/智能', '软件开发', '设计创意', '外贸出海', '教育培训', '医疗健康', '工业制造', '农业科技', '校园服务'],
demandCategories: ['全部', '智能设备', 'AI营销', '智能硬件', '铁路交通', '跨境电商', '前端开发'],
signedCategories: ['全部', '智能设备', 'AI营销', '智能硬件', '铁路交通'],
supplyItems: [],
demandItems: [],
signedItems: [],
showJoinDialog: false
};
},
computed: {
filteredItems() {
if (this.currentTab === 'supply') {
return this.supplyItems;
} else if (this.currentTab === 'demand') {
return this.demandItems;
} else if (this.currentTab === 'signed') {
return this.signedItems;
}
return [...this.supplyItems, ...this.demandItems, ...this.signedItems];
}
},
methods: {
//
openEntryFormModal() {
this.showJoinDialog = true;
},
//
handleJoinDialogClose() {
this.showJoinDialog = false;
},
// tab
switchTab(tab) {
this.currentTab = tab;
// tab
if (tab === 'supply') this.activeSupplyFilter = '全部';
if (tab === 'demand') this.activeDemandFilter = '全部';
if (tab === 'signed') this.activeSignedFilter = '全部';
},
//
filterSupply(category) {
this.activeSupplyFilter = category;
// supply tab supply tab
if (this.currentTab === 'all') {
this.currentTab = 'supply';
}
},
//
filterDemand(category) {
this.activeDemandFilter = category;
if (this.currentTab === 'all') {
this.currentTab = 'demand';
}
},
//
filterSigned(category) {
this.activeSignedFilter = category;
if (this.currentTab === 'all') {
this.currentTab = 'signed';
}
}
}
};
</script>
<style scoped lang="less">
// ==================== Font ====================
@font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif;
// ==================== Wrapper ====================
.supply-demand-wrapper {
position: relative;
width: 100%;
min-height: 100%;
height: 100%;
// overflow: hidden;
font-family: @font-family;
}
// ==================== ====================
.bg-grid {
position: fixed;
inset: 0;
pointer-events: none;
z-index: 0;
background-image: radial-gradient(rgba(59, 130, 246, 0.12) 1px, transparent 1px);
background-size: 32px 32px;
}
// ==================== ====================
.orb {
position: fixed;
border-radius: 50%;
pointer-events: none;
z-index: 0;
filter: blur(80px);
animation: orb-float 25s ease-in-out infinite;
}
.orb-1 {
width: 500px;
height: 500px;
top: -100px;
right: -100px;
background: radial-gradient(circle, #3b82f6 0%, transparent 70%);
opacity: 0.5;
animation-delay: 0s;
}
.orb-2 {
width: 600px;
height: 600px;
bottom: -150px;
left: -150px;
background: radial-gradient(circle, #1d4ed8 0%, transparent 70%);
opacity: 0.4;
animation-delay: -8s;
}
.orb-3 {
width: 400px;
height: 400px;
top: 50%;
left: 10%;
background: radial-gradient(circle, #06b6d4 0%, transparent 70%);
opacity: 0.35;
animation-delay: -16s;
}
.orb-4 {
width: 300px;
height: 300px;
top: 30%;
right: 5%;
background: radial-gradient(circle, #3b82f6 0%, transparent 70%);
opacity: 0.3;
animation-delay: -5s;
}
@keyframes orb-float {
0%, 100% { transform: translate(0, 0) scale(1); }
33% { transform: translate(25px, -25px) scale(1.03); }
66% { transform: translate(-15px, 15px) scale(0.97); }
}
// ==================== ====================
.glass-card {
border-radius: 16px;
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(24px) saturate(1.2);
-webkit-backdrop-filter: blur(24px) saturate(1.2);
border: 1px solid rgba(59, 130, 246, 0.2);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06), 0 4px 24px rgba(59, 130, 246, 0.08);
transition: all 0.3s ease;
&:hover {
border-color: rgba(59, 130, 246, 0.4);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06), 0 12px 48px rgba(59, 130, 246, 0.15);
transform: translateY(-4px);
}
}
// ==================== 广 ====================
.supply-demand {
position: relative;
z-index: 10;
padding-top: 40px;
padding-bottom: 80px;
.supply-demand-container {
max-width: 1500px;
margin: 0 auto;
padding: 0 48px;
@media (max-width: 768px) {
padding: 0 24px;
}
}
//
.supply-demand-header {
text-align: center;
margin-bottom: 48px;
.supply-demand-title {
font-size: 36px;
font-weight: 700;
margin-bottom: 16px;
background: linear-gradient(135deg, #1e40af 0%, #2563eb 40%, #3b82f6 70%, #0ea5e9 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.supply-demand-subtitle {
font-size: 18px;
color: #6b7280;
}
}
//
.process-flow {
margin-bottom: 48px;
.process-flow-title {
text-align: center;
font-size: 20px;
font-weight: 500;
color: #4b5563;
margin-bottom: 32px;
}
.process-flow-steps {
display: flex;
align-items: center;
justify-content: center;
gap: 12px;
flex-wrap: wrap;
}
}
//
.process-step {
flex: 1;
max-width: 200px;
padding: 16px;
border-radius: 16px;
cursor: pointer;
&:hover {
border-color: rgba(59, 130, 246, 0.4);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06), 0 12px 48px rgba(59, 130, 246, 0.15);
transform: translateY(-4px);
}
.process-step-header {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 8px;
}
.process-step-icon {
flex-shrink: 0;
width: 32px;
height: 32px;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
&--blue {
background-color: #eff6ff;
border: 1px solid #bfdbfe;
.process-step-icon-svg {
color: #60a5fa;
}
}
&--cyan {
background-color: #ecfeff;
border: 1px solid #a5f3fc;
.process-step-icon-svg {
color: #22d3ee;
}
}
&--emerald {
background-color: #ecfdf5;
border: 1px solid #a7f3d0;
.process-step-icon-svg {
color: #34d399;
}
}
&--teal {
background-color: #f0fdfa;
border: 1px solid #99f6e4;
.process-step-icon-svg {
color: #2dd4bf;
}
}
&--amber {
background-color: #fffbeb;
border: 1px solid #fde68a;
.process-step-icon-svg {
color: #fbbf24;
}
}
&--purple {
background-color: #faf5ff;
border: 1px solid #e9d5ff;
.process-step-icon-svg {
color: #c084fc;
}
}
}
.process-step-icon-svg {
width: 16px;
height: 16px;
}
.process-step-name {
font-size: 14px;
font-weight: 600;
color: #111827;
}
.process-step-desc {
font-size: 12px;
color: #6b7280;
}
}
//
.process-arrow {
width: 16px;
height: 16px;
color: #93c5fd;
flex-shrink: 0;
}
//
.tab-nav {
display: flex;
align-items: center;
justify-content: center;
gap: 32px;
margin-bottom: 48px;
border-bottom: 1px solid #dbeafe;
padding-bottom: 16px;
.tab-nav-item {
font-size: 14px;
font-weight: 500;
padding-bottom: 8px;
transition: color 0.2s ease;
color: #6b7280;
background: none;
border: none;
cursor: pointer;
&--active {
color: #2563eb;
border-bottom: 2px solid #2563eb;
}
&:hover {
color: #2563eb;
}
}
}
// +
.content-layout {
position: relative;
}
//
.filter-sidebar {
position: absolute;
left: 0;
top: 0;
width: 160px;
z-index: 10;
background-color: transparent;
.filter-group {
.filter-group-title {
display: flex;
align-items: center;
gap: 6px;
font-size: 13px;
font-weight: 600;
color: #4b5563;
margin-bottom: 10px;
}
.filter-group-badge {
display: inline-flex;
align-items: center;
justify-content: center;
width: 18px;
height: 18px;
border-radius: 4px;
font-size: 11px;
font-weight: 700;
color: #ffffff;
&--blue {
background: linear-gradient(135deg, #3b82f6, #2563eb);
}
&--cyan {
background: linear-gradient(135deg, #06b6d4, #0891b2);
}
&--emerald {
background: linear-gradient(135deg, #10b981, #059669);
}
}
.filter-buttons {
display: flex;
flex-direction: column;
gap: 6px;
}
}
.filter-divider {
border-top: 1px dashed #dbeafe;
margin: 14px 0;
}
}
//
.filter-btn {
padding: 8px 12px;
border-radius: 8px;
font-size: 14px;
font-weight: 500;
border: 1px solid transparent;
background: transparent;
color: #374151;
text-align: left;
cursor: pointer;
transition: all 0.25s ease;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.02);
&:hover {
color: #2563eb;
border-color: #3b82f6;
background: rgba(59, 130, 246, 0.08);
}
&--active {
color: #2563eb;
border-color: #3b82f6;
background: rgba(59, 130, 246, 0.08);
font-weight: 600;
position: relative;
&::before {
content: '';
position: absolute;
left: -1px;
top: 50%;
transform: translateY(-50%);
width: 3px;
height: 16px;
background: #2563eb;
border-radius: 0 2px 2px 0;
}
}
}
//
.card-grid {
// display: grid;
// grid-template-columns: repeat(1, 1fr);
// gap: 24px;
margin-left: 160px;
@media (min-width: 768px) {
grid-template-columns: repeat(2, 1fr);
}
@media (min-width: 1024px) {
grid-template-columns: repeat(3, 1fr);
}
}
//
.empty-state {
grid-column: 1 / -1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 80px 0;
color: #d1d5db;
.empty-state-icon {
width: 64px;
height: 64px;
margin-bottom: 16px;
color: #e5e7eb;
}
.empty-state-text {
font-size: 18px;
font-weight: 500;
}
.empty-state-hint {
font-size: 14px;
margin-top: 4px;
}
}
}
// ==================== ====================
@media (max-width: 1024px) {
.supply-demand {
.process-flow-steps {
gap: 8px;
}
.process-step {
max-width: 160px;
padding: 12px;
}
.card-grid {
margin-left: 0;
}
.filter-sidebar {
position: relative;
width: 100%;
margin-bottom: 24px;
.filter-buttons {
flex-direction: row;
flex-wrap: wrap;
}
}
}
}
@media (max-width: 768px) {
.supply-demand {
padding-top: 80px;
padding-bottom: 60px;
.supply-demand-container {
padding: 0 24px;
}
.supply-demand-header {
margin-bottom: 32px;
.supply-demand-title {
font-size: 28px;
}
.supply-demand-subtitle {
font-size: 16px;
}
}
.process-flow {
margin-bottom: 32px;
.process-flow-title {
font-size: 18px;
margin-bottom: 24px;
}
.process-flow-steps {
flex-direction: column;
align-items: center;
}
.process-arrow {
transform: rotate(90deg);
}
}
.process-step {
max-width: 240px;
width: 100%;
}
.tab-nav {
gap: 16px;
margin-bottom: 32px;
}
}
}
</style>

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,7 @@
<img src="./images/logo.png" alt="OPC数智平台" class="logo-img" />
</a>
<!-- 中间导航 -->
<!-- 中间导航 -->
<div class="nav-links">
<a href="javascript:void(0)" @click="go('/ncmatchHome/index')" class="nav-link"
:class="{ active: isActive('/ncmatchHome/index') }">首页
@ -17,8 +17,8 @@
<a href="javascript:void(0)" @click="go('/ncmatchHome/tokenMarket')" class="nav-link"
:class="{ active: isActive('/ncmatchHome/tokenMarket') }">token市集
</a>
<a href="javascript:void(0)" @click="go('/ncmatchHome/tokenMarket')" class="nav-link"
:class="{ active: isActive('/ncmatchHome/tokenMarket') }">云枢基座
<a href="javascript:void(0)" @click="go('/ncmatchHome/cloudHub')" class="nav-link"
:class="{ active: isActive('/ncmatchHome/cloudHub') }">云枢基座
</a>
<a href="javascript:void(0)" @click="go('/ncmatchHome/supplyAndDemandSquare')" class="nav-link"
:class="{ active: isActive('/ncmatchHome/supplyAndDemandSquare') }">供需广场
@ -27,14 +27,85 @@
:class="{ active: isActive('/ncmatchHome/opcOverview') }">OPC社区概况
</a>
<!-- 梦工厂 -->
<a href="javascript:void(0)" @click="go('/ncmatchHome/tokenMarket')" class="nav-link"
:class="{ active: isActive('/ncmatchHome/tokenMarket') }">梦工厂
<a href="javascript:void(0)" @click="goCreativeWorkshop" class="nav-link"
:class="{ active: isActive('') }">梦工厂
</a>
</div>
<!-- 右侧功能按钮 -->
<div class="nav-actions">
<button class="btn-login" @click="onLogin">登录</button>
<i v-if="loginState" class="iconfont icon-xiaoxi functions" @click="handleMessageClick"></i>
<button v-if="loginState" type="button" class="console-link" @click="goConsole">
控制台
</button>
<button v-if="!loginState" type="button" class="btn-login" @click="onLogin">登录</button>
<el-dropdown
v-if="loginState"
class="avatar-container right-menu-item hover-effect nick-name-style"
trigger="click"
@visible-change="handleShow"
>
<button type="button" class="login-pill login-pill--user">
{{ nick_name || '控制台' }}
<i id="resverIcon" class="el-icon-arrow-up el-icon--right resverIcon"></i>
</button>
<el-dropdown-menu slot="dropdown" style="width: 230px; font-size: 16px;" divided>
<div class="user-dropdown-head">
<span class="user-dropdown-name">{{ nick_name }}</span>
<span class="user-dropdown-id">
ID:
<span ref="contentToCopy">{{ userId }}</span>
<svg
class="copy-btn"
viewBox="0 0 1024 1024"
xmlns="http://www.w3.org/2000/svg"
width="12"
height="12"
style="fill: #1019ab;"
@click="copyBtn"
>
<path d="M394.666667 106.666667h448a74.666667 74.666667 0 0 1 74.666666 74.666666v448a74.666667 74.666667 0 0 1-74.666666 74.666667H394.666667a74.666667 74.666667 0 0 1-74.666667-74.666667V181.333333a74.666667 74.666667 0 0 1 74.666667-74.666666z m0 64a10.666667 10.666667 0 0 0-10.666667 10.666666v448a10.666667 10.666667 0 0 0 10.666667 10.666667h448a10.666667 10.666667 0 0 0 10.666666-10.666667V181.333333a10.666667 10.666667 0 0 0-10.666666-10.666666H394.666667z m245.333333 597.333333a32 32 0 0 1 64 0v74.666667a74.666667 74.666667 0 0 1-74.666667 74.666666H181.333333a74.666667 74.666667 0 0 1-74.666666-74.666666V394.666667a74.666667 74.666667 0 0 1 74.666666-74.666667h74.666667a32 32 0 0 1 0 64h-74.666667a10.666667 10.666667 0 0 0-10.666666 10.666667v448a10.666667 10.666667 0 0 0 10.666666 10.666666h448a10.666667 10.666667 0 0 0 10.666667-10.666666v-74.666667z"></path>
</svg>
</span>
</div>
<el-divider style="margin: 0 !important;"></el-divider>
<div
v-if="role.includes('客户')"
class="user-dropdown-balance"
>
<span class="moneyNow">
<span class="moneyNow-label">余额</span>
{{ mybalance ? mybalance : initMybalance() }}
</span>
<el-button
type="primary"
plain
style="padding: 8px;"
@click="$router.push('/kbossCharge')"
>
充值
</el-button>
</div>
<el-dropdown-item
v-if="role.includes('客户')"
@click.native="$router.push('/customer/customerInformation')"
>
<span style="display: block">个人中心</span>
</el-dropdown-item>
<el-dropdown-item @click.native="logout">
<span style="display: block">退出登录</span>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<div class="dropdown-wrap" id="platform-menu-wrapper">
@ -45,19 +116,46 @@
</template>
<script>
import { mapState } from 'vuex'
import store from '@/store'
import { getUserInfoAPI } from '@/api/login'
import { gotoYuanJingAPI } from '@/api/gotoYuanJing'
import { getHomePath } from '@/views/setting/tools'
export default {
name: 'TopNav',
data() {
return {
logoSrc: 'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="120" height="32"><rect width="120" height="32" fill="%23e5e7eb"/><text x="50%" y="55%" font-size="14" text-anchor="middle" fill="%236b7280" font-family="sans-serif">LOGO</text></svg>',
dropdownOpen: false,
//
role: sessionStorage.getItem('jueseNew') === 'admin' ? '' : (sessionStorage.getItem('jueseNew') || ''),
userId: sessionStorage.getItem('userId'),
nick_name: ''
};
},
computed: {
...mapState({
loginStateVuex: state => state.login.loginState,
mybalance: state => state.user.mybalance
}),
loginState() {
const userId = sessionStorage.getItem('userId');
return this.loginStateVuex || (userId !== null && userId !== 'null' && userId !== '');
}
},
created() {
if (sessionStorage.getItem('userId')) this.$store.commit('setLoginState', true)
this.getUserInfo();
this.nick_name = sessionStorage.getItem('username') || '';
},
mounted() {
document.addEventListener('click', this.handleOutsideClick);
window.addEventListener('kboss-open-login-dialog', this.handleExternalLoginOpen);
},
beforeDestroy() {
document.removeEventListener('click', this.handleOutsideClick);
window.removeEventListener('kboss-open-login-dialog', this.handleExternalLoginOpen);
},
methods: {
isActive(path) {
@ -70,6 +168,80 @@ export default {
onLogin() {
window.dispatchEvent(new Event('kboss-open-login-dialog'));
},
handleExternalLoginOpen() {
this.onLogin();
},
handleMessageClick() {
if (!this.loginState) {
this.onLogin();
return;
}
this.$message.info('消息中心暂未在 ncmatch 域开放');
},
handleShow(isShow) {
const icon = document.getElementById('resverIcon');
if (!icon) return;
icon.style.transform = isShow ? 'rotate(180deg)' : 'rotate(0)';
if (isShow && this.role.includes('客户')) {
this.$store.dispatch('user/getCustmoersMoney');
}
},
goConsole() {
const role = sessionStorage.getItem('jueseNew') || '';
if (role.includes('客户')) this.$router.push('/product/productHome').catch(() => this.$router.replace('/product/productHome'));
else if (role.includes('运营')) this.$router.push('/operation/supplierManagement');
else if (role.includes('运维')) this.$router.push('/operationAndMaintenance/workOrderProcessing');
else if (role.includes('销售')) this.$router.push('/sales/distributorManagement');
else if (role.includes('财务')) this.$router.push('/finance/supplierSettlementStatistics');
else if (role.includes('管理员')) this.$router.push('/superAdministrator/roleManagement');
else if (role.includes('admin')) this.$router.push('/superAdministrator/addAdmin');
},
initMybalance() {
return sessionStorage.getItem('mybalance');
},
copyBtn() {
const textToCopy = this.$refs.contentToCopy ? this.$refs.contentToCopy.innerText : '';
navigator.clipboard.writeText(textToCopy).then(() => {
this.$message.success('复制成功!');
}).catch(() => {
this.$message.error('复制失败,请重试');
});
},
getUserInfo() {
if (!this.userId) return;
getUserInfoAPI({ id: this.userId }).then((res) => {
if (res.status && res.data && res.data[0]) {
sessionStorage.setItem('orgid', res.data[0].orgid);
}
});
},
async logout() {
this.$store.commit('setLoginState', false);
store.commit('tagsView/resetBreadcrumbState');
store.commit('permission/RESET_ROUTES');
sessionStorage.removeItem('auths');
sessionStorage.removeItem('routes');
sessionStorage.removeItem('user');
sessionStorage.removeItem('userId');
sessionStorage.removeItem('org_type');
sessionStorage.removeItem('userType');
sessionStorage.removeItem('orgType');
sessionStorage.removeItem('roles');
sessionStorage.removeItem('juese');
sessionStorage.removeItem('jueseNew');
sessionStorage.removeItem('loginRedirectPath');
localStorage.removeItem('auths');
localStorage.removeItem('routes');
localStorage.removeItem('user');
localStorage.removeItem('userId');
localStorage.removeItem('org_type');
this.userId = '';
this.nick_name = '';
await this.$router.replace(getHomePath()).catch(() => {});
},
handleOutsideClick(e) {
const wrap = document.getElementById('platform-menu-wrapper');
if (wrap && !wrap.contains(e.target)) {
@ -78,6 +250,59 @@ export default {
this.dropdownOpen = false;
}
},
async goCreativeWorkshop() {
if (!this.loginState) {
window.open('https://ai.opencomputing.cn/', '_blank')
return
}
const yuanJingWindow = window.open('', '_blank')
try {
const res = await gotoYuanJingAPI({
user_id: sessionStorage.getItem('userId')
})
const deerer = this.getYuanJingAuthorization(res)
if (!deerer) {
if (yuanJingWindow) {
yuanJingWindow.close()
}
this.$message.error((res && res.msg) || '获取元境授权参数失败')
return
}
const loginUrl = `https://ai.opencomputing.cn/#/getCookie?deerer=${encodeURIComponent(deerer)}`
if (yuanJingWindow) {
yuanJingWindow.location.href = loginUrl
} else {
window.location.href = loginUrl
}
} catch (error) {
if (yuanJingWindow) {
yuanJingWindow.close()
}
this.$message.error('跳转元境失败,请稍后重试')
}
},
getYuanJingAuthorization(res) {
if (!res) {
return ''
}
if (typeof res === 'string') {
return res
}
const data = res.data || res
if (typeof data === 'string') {
return data
}
return data.Authorization || data.authorization || data.token || data.header || data.value || ''
},
},
};
</script>
@ -201,6 +426,124 @@ export default {
/* ==================== Dropdown ==================== */
/* ==================== Functions Icon ==================== */
.functions {
color: #000;
cursor: pointer;
font-size: 20px !important;
line-height: 1;
transition: color 0.2s ease;
}
.functions:hover {
color: #2563eb;
}
/* ==================== Console Link ==================== */
.console-link {
height: 36px;
padding: 0;
border: 0;
background: transparent;
color: #333;
cursor: pointer;
font-size: 15px !important;
font-weight: 600;
line-height: 36px;
transition: color 0.2s ease;
}
.console-link:hover {
color: #2563eb;
}
/* ==================== Login Pill (Logged-in) ==================== */
.avatar-container {
display: inline-flex;
align-items: center;
}
.login-pill {
min-width: 58px;
height: 36px;
padding: 0 20px;
border: 0;
border-radius: 999px;
background: #050505;
color: #fff;
cursor: pointer;
font-size: 15px !important;
font-weight: 600;
line-height: 36px;
display: inline-flex;
align-items: center;
gap: 6px;
}
.login-pill:hover {
opacity: 0.84;
}
.login-pill--user {
max-width: 150px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.login-pill .resverIcon {
font-size: 12px !important;
transition: transform 0.2s ease;
}
/* ==================== User Dropdown ==================== */
.user-dropdown-head {
display: flex;
flex-direction: column;
padding: 14px 16px 12px;
}
.user-dropdown-name {
font-size: 16px;
font-weight: 600;
color: #111827;
margin-bottom: 4px;
}
.user-dropdown-id {
font-size: 13px;
color: #6b7280;
display: inline-flex;
align-items: center;
gap: 6px;
}
.copy-btn {
cursor: pointer;
transition: opacity 0.2s;
}
.copy-btn:hover {
opacity: 0.7;
}
.user-dropdown-balance {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 16px;
background: #f9fafb;
}
.moneyNow {
font-size: 14px;
color: #374151;
}
.moneyNow-label {
margin-right: 6px;
color: #6b7280;
}
/* ==================== Hidden Utility ==================== */
.hidden {