2236 lines
90 KiB
HTML
2236 lines
90 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>项目管理 - 市场商务管理</title>
|
||
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
|
||
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
|
||
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
|
||
<style>
|
||
/* 基础样式 */
|
||
* {
|
||
margin: 0;
|
||
padding: 0;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
body {
|
||
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", Arial, sans-serif;
|
||
color: #333;
|
||
background-color: #f0f2f5;
|
||
}
|
||
|
||
.app-container {
|
||
display: flex;
|
||
min-height: 100vh;
|
||
overflow: hidden;
|
||
}
|
||
|
||
/* 侧边栏样式 */
|
||
.sidebar {
|
||
width: 220px;
|
||
background-color: #304156;
|
||
color: #fff;
|
||
transition: width 0.3s;
|
||
flex-shrink: 0;
|
||
overflow-y: auto;
|
||
}
|
||
|
||
.sidebar.collapsed {
|
||
width: 64px;
|
||
}
|
||
|
||
.main-content {
|
||
flex: 1;
|
||
padding: 20px;
|
||
overflow-y: auto;
|
||
transition: margin-left 0.3s;
|
||
}
|
||
|
||
.sidebar.collapsed + .main-content {
|
||
margin-left: -156px;
|
||
}
|
||
|
||
.logo {
|
||
padding: 10px 0;
|
||
text-align: center;
|
||
position: relative;
|
||
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||
}
|
||
|
||
.logo h2 {
|
||
font-size: 18px;
|
||
margin: 5px 0;
|
||
white-space: nowrap;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
padding: 0 10px;
|
||
}
|
||
|
||
.toggle-sidebar {
|
||
position: absolute;
|
||
right: 10px;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
cursor: pointer;
|
||
color: #fff;
|
||
}
|
||
|
||
/* 菜单项样式 */
|
||
.el-menu {
|
||
border-right: none;
|
||
background-color: transparent;
|
||
}
|
||
|
||
.el-menu-item, .el-submenu__title {
|
||
color: #fff;
|
||
height: 46px;
|
||
line-height: 46px;
|
||
}
|
||
|
||
.el-menu-item:hover, .el-submenu__title:hover {
|
||
background-color: rgba(0, 0, 0, 0.1) !important;
|
||
}
|
||
|
||
.el-menu-item.is-active {
|
||
background-color: rgba(0, 0, 0, 0.2) !important;
|
||
color: #409EFF !important;
|
||
}
|
||
|
||
.el-submenu .el-menu-item {
|
||
min-width: 0 !important;
|
||
padding-left: 50px !important;
|
||
background-color: #1f2d3d !important;
|
||
}
|
||
|
||
.el-submenu .el-menu-item:hover {
|
||
background-color: rgba(0, 0, 0, 0.1) !important;
|
||
}
|
||
|
||
.el-submenu__title {
|
||
padding-left: 20px !important;
|
||
}
|
||
|
||
.el-menu-item [class^=el-icon-], .el-submenu [class^=el-icon-] {
|
||
margin-right: 10px;
|
||
}
|
||
|
||
/* 主内容区样式 */
|
||
.module-title {
|
||
margin-bottom: 20px;
|
||
padding-bottom: 10px;
|
||
border-bottom: 1px solid #ebeef5;
|
||
}
|
||
|
||
.card-container {
|
||
background: #fff;
|
||
padding: 20px;
|
||
border-radius: 4px;
|
||
box-shadow: 0 2px 12px 0 rgba(0,0,0,0.1);
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
/* 表格操作按钮 */
|
||
.table-actions {
|
||
margin-bottom: 15px;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
}
|
||
|
||
/* 分页样式 */
|
||
.pagination-container {
|
||
margin-top: 20px;
|
||
text-align: right;
|
||
}
|
||
|
||
/* 表单样式 */
|
||
.form-container {
|
||
max-width: 800px;
|
||
margin: 0 auto;
|
||
}
|
||
|
||
/* 响应式调整 */
|
||
@media (max-width: 768px) {
|
||
.sidebar {
|
||
position: fixed;
|
||
z-index: 1000;
|
||
height: 100vh;
|
||
}
|
||
|
||
.sidebar.collapsed + .main-content {
|
||
margin-left: 0;
|
||
}
|
||
|
||
.main-content {
|
||
margin-left: 220px;
|
||
}
|
||
|
||
.sidebar.collapsed {
|
||
width: 0;
|
||
overflow: hidden;
|
||
}
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div id="app" class="app-container">
|
||
<!-- 侧边栏导航 -->
|
||
<div class="sidebar" :class="{collapsed: isCollapse}">
|
||
<div class="logo">
|
||
<h2>项目管理</h2>
|
||
<div class="toggle-sidebar" @click="toggleSidebar">
|
||
<i :class="isCollapse ? 'el-icon-s-unfold' : 'el-icon-s-fold'"></i>
|
||
</div>
|
||
</div>
|
||
|
||
<el-menu
|
||
:default-active="activeModule"
|
||
class="el-menu-vertical"
|
||
:collapse="isCollapse"
|
||
:collapse-transition="false"
|
||
background-color="#304156"
|
||
text-color="#fff"
|
||
active-text-color="#409EFF"
|
||
>
|
||
<!-- 市场商务管理 -->
|
||
<el-submenu index="market">
|
||
<template slot="title">
|
||
<i class="el-icon-shopping-bag-1"></i>
|
||
<span>市场商务管理</span>
|
||
</template>
|
||
|
||
<!-- 项目来源 -->
|
||
<el-submenu index="project-source">
|
||
<template slot="title">项目来源</template>
|
||
|
||
<!-- 招采业务 - 合并为一个菜单项 -->
|
||
<el-menu-item index="bidding" @click="switchModule('bidding')">招采业务</el-menu-item>
|
||
|
||
<!-- 市场营销 - 合并为一个菜单项 -->
|
||
<el-menu-item index="marketing" @click="switchModule('marketing')">市场营销</el-menu-item>
|
||
|
||
<!-- 自建项目 - 合并为一个菜单项 -->
|
||
<el-menu-item index="self-project" @click="switchModule('self-project')">自建项目</el-menu-item>
|
||
</el-submenu>
|
||
|
||
<!-- 项目合同管理 -->
|
||
<el-submenu index="contract">
|
||
<template slot="title">项目合同管理</template>
|
||
<el-menu-item index="income-contract" @click="switchModule('income-contract')">收入合同</el-menu-item>
|
||
<el-menu-item index="expense-contract" @click="switchModule('expense-contract')">支出合同</el-menu-item>
|
||
<el-menu-item index="cost-management" @click="switchModule('cost-management')">成本费用</el-menu-item>
|
||
</el-submenu>
|
||
</el-submenu>
|
||
|
||
<!-- 施工立项 -->
|
||
<el-menu-item index="construction" @click="switchModule('construction')">
|
||
<i class="el-icon-document-add"></i>
|
||
<span slot="title">施工立项</span>
|
||
</el-menu-item>
|
||
|
||
<!-- 组织实施管理 -->
|
||
<el-menu-item index="implementation" @click="switchModule('implementation')">
|
||
<i class="el-icon-s-management"></i>
|
||
<span slot="title">组织实施管理</span>
|
||
</el-menu-item>
|
||
</el-menu>
|
||
</div>
|
||
|
||
<!-- 主内容区 -->
|
||
<div class="main-content">
|
||
<!-- 招采业务 -->
|
||
<div v-if="activeModule === 'bidding'">
|
||
<h2 class="module-title">招采业务</h2>
|
||
|
||
<div class="card-container">
|
||
<el-tabs v-model="biddingTab" type="card">
|
||
<el-tab-pane label="信息检索" name="search">
|
||
<div class="table-actions">
|
||
<el-input
|
||
placeholder="搜索招标项目"
|
||
v-model="biddingSearch.keyword"
|
||
clearable
|
||
style="width: 300px;"
|
||
@keyup.enter.native="searchBiddingInfo"
|
||
>
|
||
<el-button slot="append" icon="el-icon-search" @click="searchBiddingInfo"></el-button>
|
||
</el-input>
|
||
|
||
<div>
|
||
<el-button type="primary" icon="el-icon-refresh" @click="refreshBiddingData">刷新数据</el-button>
|
||
<el-button type="success" icon="el-icon-download" @click="exportBiddingData">导出数据</el-button>
|
||
<el-button type="warning" icon="el-icon-setting" @click="showCrawlerSettings">爬虫设置</el-button>
|
||
</div>
|
||
</div>
|
||
|
||
<el-table :data="biddingData" border style="width: 100%">
|
||
<el-table-column prop="title" label="招标项目" width="300"></el-table-column>
|
||
<el-table-column prop="publisher" label="招标单位" width="180"></el-table-column>
|
||
<el-table-column prop="budget" label="预算金额" width="120" align="right"></el-table-column>
|
||
<el-table-column prop="deadline" label="截止时间" width="180"></el-table-column>
|
||
<el-table-column prop="source" label="来源平台" width="120"></el-table-column>
|
||
<el-table-column prop="status" label="状态" width="120">
|
||
<template slot-scope="scope">
|
||
<el-tag :type="scope.row.status === '进行中' ? 'success' : 'info'">
|
||
{{ scope.row.status }}
|
||
</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="操作" width="180">
|
||
<template slot-scope="scope">
|
||
<el-button size="mini" @click="viewBiddingDetail(scope.row)">详情</el-button>
|
||
<el-button size="mini" type="primary" @click="markAsInterested(scope.row)">关注</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
|
||
<div class="pagination-container">
|
||
<el-pagination
|
||
@size-change="handleBiddingSizeChange"
|
||
@current-change="handleBiddingCurrentChange"
|
||
:current-page="biddingSearch.page"
|
||
:page-sizes="[10, 20, 50, 100]"
|
||
:page-size="biddingSearch.limit"
|
||
layout="total, sizes, prev, pager, next, jumper"
|
||
:total="biddingTotal">
|
||
</el-pagination>
|
||
</div>
|
||
|
||
<!-- 招标详情对话框 -->
|
||
<el-dialog title="招标详情" :visible.sync="biddingDetailVisible" width="70%">
|
||
<div v-if="currentBidding">
|
||
<el-descriptions :column="2" border>
|
||
<el-descriptions-item label="项目名称">{{ currentBidding.title }}</el-descriptions-item>
|
||
<el-descriptions-item label="招标单位">{{ currentBidding.publisher }}</el-descriptions-item>
|
||
<el-descriptions-item label="预算金额">{{ currentBidding.budget }}</el-descriptions-item>
|
||
<el-descriptions-item label="截止时间">{{ currentBidding.deadline }}</el-descriptions-item>
|
||
<el-descriptions-item label="项目地点">{{ currentBidding.location }}</el-descriptions-item>
|
||
<el-descriptions-item label="项目周期">{{ currentBidding.duration }}</el-descriptions-item>
|
||
<el-descriptions-item label="招标范围" :span="2">{{ currentBidding.scope }}</el-descriptions-item>
|
||
<el-descriptions-item label="资质要求" :span="2">{{ currentBidding.qualification }}</el-descriptions-item>
|
||
<el-descriptions-item label="招标文件" :span="2">
|
||
<el-link type="primary" :href="currentBidding.docUrl" target="_blank">下载招标文件</el-link>
|
||
</el-descriptions-item>
|
||
</el-descriptions>
|
||
|
||
<div style="margin-top: 20px;">
|
||
<h3>招标内容</h3>
|
||
<div v-html="currentBidding.content" style="border: 1px solid #ebeef5; padding: 10px; border-radius: 4px;"></div>
|
||
</div>
|
||
</div>
|
||
<span slot="footer" class="dialog-footer">
|
||
<el-button @click="biddingDetailVisible = false">关闭</el-button>
|
||
<el-button type="primary" @click="goToBiddingResponse">投标响应</el-button>
|
||
</span>
|
||
</el-dialog>
|
||
|
||
<!-- 爬虫设置对话框 -->
|
||
<el-dialog title="爬虫设置" :visible.sync="crawlerSettingsVisible" width="50%">
|
||
<el-form :model="crawlerSettings" label-width="120px">
|
||
<el-form-item label="爬取频率">
|
||
<el-select v-model="crawlerSettings.frequency" style="width: 200px;">
|
||
<el-option label="每小时" value="hourly"></el-option>
|
||
<el-option label="每天" value="daily"></el-option>
|
||
<el-option label="每周" value="weekly"></el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="关键词过滤">
|
||
<el-tag
|
||
v-for="tag in crawlerSettings.keywords"
|
||
:key="tag"
|
||
closable
|
||
@close="removeKeyword(tag)"
|
||
style="margin-right: 10px;"
|
||
>
|
||
{{ tag }}
|
||
</el-tag>
|
||
<el-input
|
||
v-model="newKeyword"
|
||
size="small"
|
||
style="width: 150px;"
|
||
@keyup.enter.native="addKeyword"
|
||
>
|
||
<el-button slot="append" icon="el-icon-plus" @click="addKeyword"></el-button>
|
||
</el-input>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="来源平台">
|
||
<el-checkbox-group v-model="crawlerSettings.platforms">
|
||
<el-checkbox label="中国招标投标公共服务平台"></el-checkbox>
|
||
<el-checkbox label="各省市公共资源交易中心"></el-checkbox>
|
||
<el-checkbox label="企业自有招标平台"></el-checkbox>
|
||
<el-checkbox label="其他第三方平台"></el-checkbox>
|
||
</el-checkbox-group>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="自动通知">
|
||
<el-switch v-model="crawlerSettings.autoNotify"></el-switch>
|
||
<span style="margin-left: 10px;">{{ crawlerSettings.autoNotify ? '已开启' : '已关闭' }}</span>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="通知方式" v-if="crawlerSettings.autoNotify">
|
||
<el-checkbox-group v-model="crawlerSettings.notifyMethods">
|
||
<el-checkbox label="站内消息"></el-checkbox>
|
||
<el-checkbox label="电子邮件"></el-checkbox>
|
||
<el-checkbox label="手机短信"></el-checkbox>
|
||
</el-checkbox-group>
|
||
</el-form-item>
|
||
</el-form>
|
||
<span slot="footer" class="dialog-footer">
|
||
<el-button @click="crawlerSettingsVisible = false">取消</el-button>
|
||
<el-button type="primary" @click="saveCrawlerSettings">保存设置</el-button>
|
||
</span>
|
||
</el-dialog>
|
||
</el-tab-pane>
|
||
|
||
<el-tab-pane label="投标响应" name="response">
|
||
<el-tabs v-model="biddingResponseTab">
|
||
<el-tab-pane label="投标项目" name="projects">
|
||
<div class="table-actions">
|
||
<el-input
|
||
placeholder="搜索投标项目"
|
||
v-model="biddingResponseSearch.keyword"
|
||
clearable
|
||
style="width: 300px;"
|
||
>
|
||
<el-button slot="append" icon="el-icon-search"></el-button>
|
||
</el-input>
|
||
|
||
<div>
|
||
<el-button type="primary" icon="el-icon-plus" @click="showNewBiddingDialog">新建投标</el-button>
|
||
<el-button icon="el-icon-refresh" @click="refreshBiddingResponse">刷新</el-button>
|
||
</div>
|
||
</div>
|
||
|
||
<el-table :data="biddingResponseData" border style="width: 100%">
|
||
<el-table-column prop="projectName" label="项目名称" width="250"></el-table-column>
|
||
<el-table-column prop="publisher" label="招标单位" width="150"></el-table-column>
|
||
<el-table-column prop="budget" label="预算金额" width="120" align="right"></el-table-column>
|
||
<el-table-column prop="deadline" label="截止时间" width="150"></el-table-column>
|
||
<el-table-column prop="status" label="投标状态" width="120">
|
||
<template slot-scope="scope">
|
||
<el-tag :type="scope.row.status === '已中标' ? 'success' :
|
||
scope.row.status === '已投标' ? 'primary' :
|
||
scope.row.status === '准备中' ? 'warning' : 'info'">
|
||
{{ scope.row.status }}
|
||
</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="progress" label="进度" width="150">
|
||
<template slot-scope="scope">
|
||
<el-progress :percentage="scope.row.progress" :status="scope.row.status === '已中标' ? 'success' : ''"></el-progress>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="操作" width="200">
|
||
<template slot-scope="scope">
|
||
<el-button size="mini" @click="viewBiddingResponse(scope.row)">详情</el-button>
|
||
<el-button size="mini" type="primary" @click="editBiddingResponse(scope.row)"
|
||
:disabled="scope.row.status === '已中标' || scope.row.status === '已投标'">编辑</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
|
||
<div class="pagination-container">
|
||
<el-pagination
|
||
@size-change="handleBiddingResponseSizeChange"
|
||
@current-change="handleBiddingResponseCurrentChange"
|
||
:current-page="biddingResponseSearch.page"
|
||
:page-sizes="[10, 20, 50, 100]"
|
||
:page-size="biddingResponseSearch.limit"
|
||
layout="total, sizes, prev, pager, next, jumper"
|
||
:total="biddingResponseTotal">
|
||
</el-pagination>
|
||
</div>
|
||
</el-tab-pane>
|
||
|
||
<el-tab-pane label="商务标书" name="documents">
|
||
<div class="table-actions">
|
||
<el-input
|
||
placeholder="搜索标书"
|
||
v-model="documentSearch.keyword"
|
||
clearable
|
||
style="width: 300px;"
|
||
>
|
||
<el-button slot="append" icon="el-icon-search"></el-button>
|
||
</el-input>
|
||
|
||
<div>
|
||
<el-button type="primary" icon="el-icon-plus" @click="showNewDocumentDialog">新建标书</el-button>
|
||
<el-button icon="el-icon-refresh" @click="refreshDocuments">刷新</el-button>
|
||
</div>
|
||
</div>
|
||
|
||
<el-table :data="documentData" border style="width: 100%">
|
||
<el-table-column prop="name" label="标书名称" width="250"></el-table-column>
|
||
<el-table-column prop="project" label="关联项目" width="200"></el-table-column>
|
||
<el-table-column prop="type" label="标书类型" width="120">
|
||
<template slot-scope="scope">
|
||
<el-tag>{{ scope.row.type }}</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="version" label="版本" width="100"></el-table-column>
|
||
<el-table-column prop="updateTime" label="更新时间" width="180"></el-table-column>
|
||
<el-table-column prop="status" label="状态" width="120">
|
||
<template slot-scope="scope">
|
||
<el-tag :type="scope.row.status === '已完成' ? 'success' : 'warning'">
|
||
{{ scope.row.status }}
|
||
</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="操作" width="200">
|
||
<template slot-scope="scope">
|
||
<el-button size="mini" @click="viewDocument(scope.row)">查看</el-button>
|
||
<el-button size="mini" type="primary" @click="editDocument(scope.row)">编辑</el-button>
|
||
<el-button size="mini" type="success" @click="generateDocument(scope.row)">生成</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
|
||
<div class="pagination-container">
|
||
<el-pagination
|
||
@size-change="handleDocumentSizeChange"
|
||
@current-change="handleDocumentCurrentChange"
|
||
:current-page="documentSearch.page"
|
||
:page-sizes="[10, 20, 50, 100]"
|
||
:page-size="documentSearch.limit"
|
||
layout="total, sizes, prev, pager, next, jumper"
|
||
:total="documentTotal">
|
||
</el-pagination>
|
||
</div>
|
||
</el-tab-pane>
|
||
|
||
<el-tab-pane label="报价文件" name="quotations">
|
||
<div class="table-actions">
|
||
<el-input
|
||
placeholder="搜索报价文件"
|
||
v-model="quotationSearch.keyword"
|
||
clearable
|
||
style="width: 300px;"
|
||
>
|
||
<el-button slot="append" icon="el-icon-search"></el-button>
|
||
</el-input>
|
||
|
||
<div>
|
||
<el-button type="primary" icon="el-icon-plus" @click="showNewQuotationDialog">新建报价</el-button>
|
||
<el-button icon="el-icon-refresh" @click="refreshQuotations">刷新</el-button>
|
||
</div>
|
||
</div>
|
||
|
||
<el-table :data="quotationData" border style="width: 100%">
|
||
<el-table-column prop="name" label="报价文件" width="250"></el-table-column>
|
||
<el-table-column prop="project" label="关联项目" width="200"></el-table-column>
|
||
<el-table-column prop="totalPrice" label="总报价" width="120" align="right"></el-table-column>
|
||
<el-table-column prop="profitRate" label="利润率" width="120">
|
||
<template slot-scope="scope">
|
||
<el-tag :type="scope.row.profitRate >= 20 ? 'success' : scope.row.profitRate >= 10 ? 'warning' : 'danger'">
|
||
{{ scope.row.profitRate }}%
|
||
</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="updateTime" label="更新时间" width="180"></el-table-column>
|
||
<el-table-column prop="status" label="状态" width="120">
|
||
<template slot-scope="scope">
|
||
<el-tag :type="scope.row.status === '已确认' ? 'success' : 'warning'">
|
||
{{ scope.row.status }}
|
||
</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="操作" width="200">
|
||
<template slot-scope="scope">
|
||
<el-button size="mini" @click="viewQuotation(scope.row)">查看</el-button>
|
||
<el-button size="mini" type="primary" @click="editQuotation(scope.row)">编辑</el-button>
|
||
<el-button size="mini" type="success" @click="confirmQuotation(scope.row)"
|
||
:disabled="scope.row.status === '已确认'">确认</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
|
||
<div class="pagination-container">
|
||
<el-pagination
|
||
@size-change="handleQuotationSizeChange"
|
||
@current-change="handleQuotationCurrentChange"
|
||
:current-page="quotationSearch.page"
|
||
:page-sizes="[10, 20, 50, 100]"
|
||
:page-size="quotationSearch.limit"
|
||
layout="total, sizes, prev, pager, next, jumper"
|
||
:total="quotationTotal">
|
||
</el-pagination>
|
||
</div>
|
||
</el-tab-pane>
|
||
|
||
<el-tab-pane label="中标通知" name="notices">
|
||
<div class="table-actions">
|
||
<el-input
|
||
placeholder="搜索中标通知"
|
||
v-model="noticeSearch.keyword"
|
||
clearable
|
||
style="width: 300px;"
|
||
>
|
||
<el-button slot="append" icon="el-icon-search"></el-button>
|
||
</el-input>
|
||
|
||
<div>
|
||
<el-button type="primary" icon="el-icon-download" @click="exportNotices">导出数据</el-button>
|
||
<el-button icon="el-icon-refresh" @click="refreshNotices">刷新</el-button>
|
||
</div>
|
||
</div>
|
||
|
||
<el-table :data="noticeData" border style="width: 100%">
|
||
<el-table-column prop="projectName" label="项目名称" width="250"></el-table-column>
|
||
<el-table-column prop="publisher" label="招标单位" width="150"></el-table-column>
|
||
<el-table-column prop="winningPrice" label="中标金额" width="120" align="right"></el-table-column>
|
||
<el-table-column prop="noticeDate" label="通知日期" width="150"></el-table-column>
|
||
<el-table-column prop="status" label="状态" width="120">
|
||
<template slot-scope="scope">
|
||
<el-tag :type="scope.row.status === '已签约' ? 'success' :
|
||
scope.row.status === '已确认' ? 'primary' : 'warning'">
|
||
{{ scope.row.status }}
|
||
</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="操作" width="200">
|
||
<template slot-scope="scope">
|
||
<el-button size="mini" @click="viewNotice(scope.row)">查看</el-button>
|
||
<el-button size="mini" type="primary" @click="processNotice(scope.row)">处理</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
|
||
<div class="pagination-container">
|
||
<el-pagination
|
||
@size-change="handleNoticeSizeChange"
|
||
@current-change="handleNoticeCurrentChange"
|
||
:current-page="noticeSearch.page"
|
||
:page-sizes="[10, 20, 50, 100]"
|
||
:page-size="noticeSearch.limit"
|
||
layout="total, sizes, prev, pager, next, jumper"
|
||
:total="noticeTotal">
|
||
</el-pagination>
|
||
</div>
|
||
</el-tab-pane>
|
||
</el-tabs>
|
||
|
||
<!-- 新建投标对话框 -->
|
||
<el-dialog title="新建投标项目" :visible.sync="newBiddingDialogVisible" width="50%">
|
||
<el-form :model="newBiddingForm" :rules="biddingRules" ref="newBiddingForm" label-width="120px">
|
||
<el-form-item label="项目名称" prop="projectName">
|
||
<el-input v-model="newBiddingForm.projectName"></el-input>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="招标单位" prop="publisher">
|
||
<el-input v-model="newBiddingForm.publisher"></el-input>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="预算金额" prop="budget">
|
||
<el-input v-model="newBiddingForm.budget" style="width: 200px;">
|
||
<template slot="append">万元</template>
|
||
</el-input>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="截止时间" prop="deadline">
|
||
<el-date-picker
|
||
v-model="newBiddingForm.deadline"
|
||
type="datetime"
|
||
placeholder="选择日期时间"
|
||
value-format="yyyy-MM-dd HH:mm:ss">
|
||
</el-date-picker>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="项目地点" prop="location">
|
||
<el-cascader
|
||
v-model="newBiddingForm.location"
|
||
:options="locationOptions"
|
||
style="width: 100%;"
|
||
></el-cascader>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="项目类型" prop="projectType">
|
||
<el-select v-model="newBiddingForm.projectType" style="width: 100%;">
|
||
<el-option label="风电叶片检查" value="wind-power"></el-option>
|
||
<el-option label="风电运维" value="maintenance"></el-option>
|
||
<el-option label="风电安装" value="installation"></el-option>
|
||
<el-option label="其他" value="other"></el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="招标文件" prop="docUrl">
|
||
<el-upload
|
||
class="upload-demo"
|
||
action=""
|
||
:on-change="handleBiddingFileChange"
|
||
:auto-upload="false"
|
||
:file-list="biddingFileList"
|
||
>
|
||
<el-button size="small" type="primary">点击上传</el-button>
|
||
<div slot="tip" class="el-upload__tip">请上传招标文件</div>
|
||
</el-upload>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="项目描述" prop="description">
|
||
<el-input type="textarea" v-model="newBiddingForm.description" :rows="3"></el-input>
|
||
</el-form-item>
|
||
</el-form>
|
||
<span slot="footer" class="dialog-footer">
|
||
<el-button @click="newBiddingDialogVisible = false">取消</el-button>
|
||
<el-button type="primary" @click="submitNewBidding">确定</el-button>
|
||
</span>
|
||
</el-dialog>
|
||
</el-tab-pane>
|
||
</el-tabs>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 市场营销 -->
|
||
<div v-if="activeModule === 'marketing'">
|
||
<h2 class="module-title">市场营销</h2>
|
||
|
||
<div class="card-container">
|
||
<el-tabs v-model="marketingTab" type="card">
|
||
<el-tab-pane label="营销推广" name="promotion">
|
||
<el-tabs v-model="marketingSubTab">
|
||
<el-tab-pane label="营销活动" name="activities">
|
||
<div class="table-actions">
|
||
<el-input
|
||
placeholder="搜索营销活动"
|
||
v-model="activitySearch.keyword"
|
||
clearable
|
||
style="width: 300px;"
|
||
>
|
||
<el-button slot="append" icon="el-icon-search"></el-button>
|
||
</el-input>
|
||
|
||
<div>
|
||
<el-button type="primary" icon="el-icon-plus" @click="showNewActivityDialog">新建活动</el-button>
|
||
<el-button icon="el-icon-refresh" @click="refreshActivities">刷新</el-button>
|
||
</div>
|
||
</div>
|
||
|
||
<el-table :data="activityData" border style="width: 100%">
|
||
<el-table-column prop="name" label="活动名称" width="250"></el-table-column>
|
||
<el-table-column prop="type" label="活动类型" width="120">
|
||
<template slot-scope="scope">
|
||
<el-tag>{{ scope.row.type }}</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="startDate" label="开始时间" width="180"></el-table-column>
|
||
<el-table-column prop="endDate" label="结束时间" width="180"></el-table-column>
|
||
<el-table-column prop="budget" label="预算" width="120" align="right"></el-table-column>
|
||
<el-table-column prop="status" label="状态" width="120">
|
||
<template slot-scope="scope">
|
||
<el-tag :type="scope.row.status === '进行中' ? 'success' :
|
||
scope.row.status === '已结束' ? 'info' : 'warning'">
|
||
{{ scope.row.status }}
|
||
</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="操作" width="180">
|
||
<template slot-scope="scope">
|
||
<el-button size="mini" @click="viewActivity(scope.row)">详情</el-button>
|
||
<el-button size="mini" type="primary" @click="editActivity(scope.row)">编辑</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
|
||
<div class="pagination-container">
|
||
<el-pagination
|
||
@size-change="handleActivitySizeChange"
|
||
@current-change="handleActivityCurrentChange"
|
||
:current-page="activitySearch.page"
|
||
:page-sizes="[10, 20, 50, 100]"
|
||
:page-size="activitySearch.limit"
|
||
layout="total, sizes, prev, pager, next, jumper"
|
||
:total="activityTotal">
|
||
</el-pagination>
|
||
</div>
|
||
</el-tab-pane>
|
||
|
||
<el-tab-pane label="客户管理" name="clients">
|
||
<div class="table-actions">
|
||
<el-input
|
||
placeholder="搜索客户"
|
||
v-model="clientSearch.keyword"
|
||
clearable
|
||
style="width: 300px;"
|
||
>
|
||
<el-button slot="append" icon="el-icon-search"></el-button>
|
||
</el-input>
|
||
|
||
<div>
|
||
<el-button type="primary" icon="el-icon-plus" @click="showNewClientDialog">新增客户</el-button>
|
||
<el-button icon="el-icon-refresh" @click="refreshClients">刷新</el-button>
|
||
</div>
|
||
</div>
|
||
|
||
<el-table :data="clientData" border style="width: 100%">
|
||
<el-table-column prop="name" label="客户名称" width="200"></el-table-column>
|
||
<el-table-column prop="industry" label="所属行业" width="150"></el-table-column>
|
||
<el-table-column prop="contact" label="联系人" width="120"></el-table-column>
|
||
<el-table-column prop="phone" label="联系电话" width="150"></el-table-column>
|
||
<el-table-column prop="level" label="客户等级" width="120">
|
||
<template slot-scope="scope">
|
||
<el-tag :type="scope.row.level === 'A' ? 'success' :
|
||
scope.row.level === 'B' ? 'primary' : 'warning'">
|
||
{{ scope.row.level }}级
|
||
</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="lastContact" label="最后联系" width="180"></el-table-column>
|
||
<el-table-column label="操作" width="180">
|
||
<template slot-scope="scope">
|
||
<el-button size="mini" @click="viewClient(scope.row)">详情</el-button>
|
||
<el-button size="mini" type="primary" @click="editClient(scope.row)">编辑</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
|
||
<div class="pagination-container">
|
||
<el-pagination
|
||
@size-change="handleClientSizeChange"
|
||
@current-change="handleClientCurrentChange"
|
||
:current-page="clientSearch.page"
|
||
:page-sizes="[10, 20, 50, 100]"
|
||
:page-size="clientSearch.limit"
|
||
layout="total, sizes, prev, pager, next, jumper"
|
||
:total="clientTotal">
|
||
</el-pagination>
|
||
</div>
|
||
</el-tab-pane>
|
||
|
||
<el-tab-pane label="营销效果" name="effect">
|
||
<div style="margin-bottom: 20px;">
|
||
<el-date-picker
|
||
v-model="effectDateRange"
|
||
type="daterange"
|
||
align="right"
|
||
unlink-panels
|
||
range-separator="至"
|
||
start-placeholder="开始日期"
|
||
end-placeholder="结束日期"
|
||
:picker-options="pickerOptions"
|
||
style="width: 300px;"
|
||
>
|
||
</el-date-picker>
|
||
<el-button type="primary" @click="loadEffectData" style="margin-left: 20px;">查询</el-button>
|
||
</div>
|
||
|
||
<div style="display: flex; margin-bottom: 20px;">
|
||
<div style="flex: 1; margin-right: 20px;">
|
||
<el-card shadow="hover">
|
||
<div slot="header">新增客户</div>
|
||
<div style="font-size: 24px; text-align: center;">{{ effectData.newClients }}</div>
|
||
</el-card>
|
||
</div>
|
||
<div style="flex: 1; margin-right: 20px;">
|
||
<el-card shadow="hover">
|
||
<div slot="header">商机数量</div>
|
||
<div style="font-size: 24px; text-align: center;">{{ effectData.opportunities }}</div>
|
||
</el-card>
|
||
</div>
|
||
<div style="flex: 1;">
|
||
<el-card shadow="hover">
|
||
<div slot="header">转化率</div>
|
||
<div style="font-size: 24px; text-align: center;">{{ effectData.conversionRate }}%</div>
|
||
</el-card>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="height: 400px; margin-bottom: 20px;">
|
||
<div id="effectChart" style="width: 100%; height: 100%;"></div>
|
||
</div>
|
||
</el-tab-pane>
|
||
</el-tabs>
|
||
</el-tab-pane>
|
||
|
||
<el-tab-pane label="框架协议" name="agreement">
|
||
<div class="table-actions">
|
||
<el-input
|
||
placeholder="搜索框架协议"
|
||
v-model="agreementSearch.keyword"
|
||
clearable
|
||
style="width: 300px;"
|
||
>
|
||
<el-button slot="append" icon="el-icon-search"></el-button>
|
||
</el-input>
|
||
|
||
<div>
|
||
<el-button type="primary" icon="el-icon-plus" @click="showNewAgreementDialog">新建协议</el-button>
|
||
<el-button icon="el-icon-refresh" @click="refreshAgreements">刷新</el-button>
|
||
</div>
|
||
</div>
|
||
|
||
<el-table :data="agreementData" border style="width: 100%">
|
||
<el-table-column prop="name" label="协议名称" width="250"></el-table-column>
|
||
<el-table-column prop="client" label="客户名称" width="200"></el-table-column>
|
||
<el-table-column prop="startDate" label="开始日期" width="150"></el-table-column>
|
||
<el-table-column prop="endDate" label="结束日期" width="150"></el-table-column>
|
||
<el-table-column prop="amount" label="预估金额" width="120" align="right"></el-table-column>
|
||
<el-table-column prop="status" label="状态" width="120">
|
||
<template slot-scope="scope">
|
||
<el-tag :type="scope.row.status === '有效' ? 'success' : 'info'">
|
||
{{ scope.row.status }}
|
||
</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="操作" width="200">
|
||
<template slot-scope="scope">
|
||
<el-button size="mini" @click="viewAgreement(scope.row)">查看</el-button>
|
||
<el-button size="mini" type="primary" @click="editAgreement(scope.row)">编辑</el-button>
|
||
<el-button size="mini" type="danger" @click="terminateAgreement(scope.row)"
|
||
:disabled="scope.row.status !== '有效'">终止</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
|
||
<div class="pagination-container">
|
||
<el-pagination
|
||
@size-change="handleAgreementSizeChange"
|
||
@current-change="handleAgreementCurrentChange"
|
||
:current-page="agreementSearch.page"
|
||
:page-sizes="[10, 20, 50, 100]"
|
||
:page-size="agreementSearch.limit"
|
||
layout="total, sizes, prev, pager, next, jumper"
|
||
:total="agreementTotal">
|
||
</el-pagination>
|
||
</div>
|
||
</el-tab-pane>
|
||
|
||
<el-tab-pane label="同行业务" name="industry">
|
||
<el-tabs v-model="industryTab">
|
||
<el-tab-pane label="竞争对手" name="competitors">
|
||
<div class="table-actions">
|
||
<el-input
|
||
placeholder="搜索竞争对手"
|
||
v-model="competitorSearch.keyword"
|
||
clearable
|
||
style="width: 300px;"
|
||
>
|
||
<el-button slot="append" icon="el-icon-search"></el-button>
|
||
</el-input>
|
||
|
||
<div>
|
||
<el-button type="primary" icon="el-icon-plus" @click="showNewCompetitorDialog">新增对手</el-button>
|
||
<el-button icon="el-icon-refresh" @click="refreshCompetitors">刷新</el-button>
|
||
</div>
|
||
</div>
|
||
|
||
<el-table :data="competitorData" border style="width: 100%">
|
||
<el-table-column prop="name" label="公司名称" width="250"></el-table-column>
|
||
<el-table-column prop="strength" label="优势领域" width="200"></el-table-column>
|
||
<el-table-column prop="marketShare" label="市场份额" width="120">
|
||
<template slot-scope="scope">
|
||
{{ scope.row.marketShare }}%
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="recentProjects" label="近期项目" width="150"></el-table-column>
|
||
<el-table-column label="竞争等级" width="120">
|
||
<template slot-scope="scope">
|
||
<el-rate
|
||
v-model="scope.row.level"
|
||
disabled
|
||
show-text
|
||
:texts="['弱', '一般', '较强', '强', '很强']"
|
||
></el-rate>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="操作" width="180">
|
||
<template slot-scope="scope">
|
||
<el-button size="mini" @click="viewCompetitor(scope.row)">详情</el-button>
|
||
<el-button size="mini" type="primary" @click="editCompetitor(scope.row)">编辑</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
|
||
<div class="pagination-container">
|
||
<el-pagination
|
||
@size-change="handleCompetitorSizeChange"
|
||
@current-change="handleCompetitorCurrentChange"
|
||
:current-page="competitorSearch.page"
|
||
:page-sizes="[10, 20, 50, 100]"
|
||
:page-size="competitorSearch.limit"
|
||
layout="total, sizes, prev, pager, next, jumper"
|
||
:total="competitorTotal">
|
||
</el-pagination>
|
||
</div>
|
||
</el-tab-pane>
|
||
|
||
<el-tab-pane label="市场分析" name="analysis">
|
||
<div style="margin-bottom: 20px;">
|
||
<el-date-picker
|
||
v-model="analysisYear"
|
||
type="year"
|
||
placeholder="选择年份"
|
||
value-format="yyyy"
|
||
style="width: 200px;"
|
||
>
|
||
</el-date-picker>
|
||
<el-button type="primary" @click="loadAnalysisData" style="margin-left: 20px;">查询</el-button>
|
||
</div>
|
||
|
||
<div style="height: 400px; margin-bottom: 20px;">
|
||
<div id="marketShareChart" style="width: 100%; height: 100%;"></div>
|
||
</div>
|
||
|
||
<div style="height: 400px;">
|
||
<div id="priceTrendChart" style="width: 100%; height: 100%;"></div>
|
||
</div>
|
||
</el-tab-pane>
|
||
|
||
<el-tab-pane label="议价策略" name="strategy">
|
||
<div style="margin-bottom: 20px;">
|
||
<el-button type="primary" icon="el-icon-plus" @click="showNewStrategyDialog">新建策略</el-button>
|
||
</div>
|
||
|
||
<el-table :data="strategyData" border style="width: 100%">
|
||
<el-table-column prop="name" label="策略名称" width="250"></el-table-column>
|
||
<el-table-column prop="target" label="目标客户" width="200"></el-table-column>
|
||
<el-table-column prop="discount" label="折扣范围" width="120">
|
||
<template slot-scope="scope">
|
||
{{ scope.row.discount }}%
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="conditions" label="适用条件" width="200"></el-table-column>
|
||
<el-table-column prop="effectiveness" label="有效性" width="120">
|
||
<template slot-scope="scope">
|
||
<el-tag :type="scope.row.effectiveness === '高' ? 'success' :
|
||
scope.row.effectiveness === '中' ? 'warning' : 'danger'">
|
||
{{ scope.row.effectiveness }}
|
||
</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="操作" width="180">
|
||
<template slot-scope="scope">
|
||
<el-button size="mini" @click="viewStrategy(scope.row)">详情</el-button>
|
||
<el-button size="mini" type="primary" @click="editStrategy(scope.row)">编辑</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
|
||
<div class="pagination-container">
|
||
<el-pagination
|
||
@size-change="handleStrategySizeChange"
|
||
@current-change="handleStrategyCurrentChange"
|
||
:current-page="strategySearch.page"
|
||
:page-sizes="[10, 20, 50, 100]"
|
||
:page-size="strategySearch.limit"
|
||
layout="total, sizes, prev, pager, next, jumper"
|
||
:total="strategyTotal">
|
||
</el-pagination>
|
||
</div>
|
||
</el-tab-pane>
|
||
</el-tabs>
|
||
</el-tab-pane>
|
||
</el-tabs>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 自建项目 -->
|
||
<div v-if="activeModule === 'self-project'">
|
||
<h2 class="module-title">自建项目</h2>
|
||
|
||
<div class="card-container">
|
||
<el-tabs v-model="selfProjectTab" type="card">
|
||
<el-tab-pane label="软件开发" name="software">
|
||
<div class="table-actions">
|
||
<el-input
|
||
placeholder="搜索软件项目"
|
||
v-model="softwareSearch.keyword"
|
||
clearable
|
||
style="width: 300px;"
|
||
>
|
||
<el-button slot="append" icon="el-icon-search"></el-button>
|
||
</el-input>
|
||
|
||
<div>
|
||
<el-button type="primary" icon="el-icon-plus" @click="showNewSoftwareDialog">新建项目</el-button>
|
||
<el-button icon="el-icon-refresh" @click="refreshSoftwareProjects">刷新</el-button>
|
||
</div>
|
||
</div>
|
||
|
||
<el-table :data="softwareData" border style="width: 100%">
|
||
<el-table-column prop="name" label="项目名称" width="250"></el-table-column>
|
||
<el-table-column prop="type" label="项目类型" width="150">
|
||
<template slot-scope="scope">
|
||
<el-tag>{{ scope.row.type }}</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="manager" label="项目经理" width="120"></el-table-column>
|
||
<el-table-column prop="startDate" label="开始日期" width="150"></el-table-column>
|
||
<el-table-column prop="endDate" label="计划完成" width="150"></el-table-column>
|
||
<el-table-column prop="progress" label="进度" width="150">
|
||
<template slot-scope="scope">
|
||
<el-progress :percentage="scope.row.progress" :status="scope.row.progress === 100 ? 'success' : ''"></el-progress>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="操作" width="180">
|
||
<template slot-scope="scope">
|
||
<el-button size="mini" @click="viewSoftwareProject(scope.row)">详情</el-button>
|
||
<el-button size="mini" type="primary" @click="editSoftwareProject(scope.row)">编辑</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
|
||
<div class="pagination-container">
|
||
<el-pagination
|
||
@size-change="handleSoftwareSizeChange"
|
||
@current-change="handleSoftwareCurrentChange"
|
||
:current-page="softwareSearch.page"
|
||
:page-sizes="[10, 20, 50, 100]"
|
||
:page-size="softwareSearch.limit"
|
||
layout="total, sizes, prev, pager, next, jumper"
|
||
:total="softwareTotal">
|
||
</el-pagination>
|
||
</div>
|
||
</el-tab-pane>
|
||
|
||
<el-tab-pane label="硬件开发" name="hardware">
|
||
<div class="table-actions">
|
||
<el-input
|
||
placeholder="搜索硬件项目"
|
||
v-model="hardwareSearch.keyword"
|
||
clearable
|
||
style="width: 300px;"
|
||
>
|
||
<el-button slot="append" icon="el-icon-search"></el-button>
|
||
</el-input>
|
||
|
||
<div>
|
||
<el-button type="primary" icon="el-icon-plus" @click="showNewHardwareDialog">新建项目</el-button>
|
||
<el-button icon="el-icon-refresh" @click="refreshHardwareProjects">刷新</el-button>
|
||
</div>
|
||
</div>
|
||
|
||
<el-table :data="hardwareData" border style="width: 100%">
|
||
<el-table-column prop="name" label="项目名称" width="250"></el-table-column>
|
||
<el-table-column prop="type" label="项目类型" width="150">
|
||
<template slot-scope="scope">
|
||
<el-tag>{{ scope.row.type }}</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="manager" label="项目经理" width="120"></el-table-column>
|
||
<el-table-column prop="startDate" label="开始日期" width="150"></el-table-column>
|
||
<el-table-column prop="endDate" label="计划完成" width="150"></el-table-column>
|
||
<el-table-column prop="progress" label="进度" width="150">
|
||
<template slot-scope="scope">
|
||
<el-progress :percentage="scope.row.progress" :status="scope.row.progress === 100 ? 'success' : ''"></el-progress>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="操作" width="180">
|
||
<template slot-scope="scope">
|
||
<el-button size="mini" @click="viewHardwareProject(scope.row)">详情</el-button>
|
||
<el-button size="mini" type="primary" @click="editHardwareProject(scope.row)">编辑</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
|
||
<div class="pagination-container">
|
||
<el-pagination
|
||
@size-change="handleHardwareSizeChange"
|
||
@current-change="handleHardwareCurrentChange"
|
||
:current-page="hardwareSearch.page"
|
||
:page-sizes="[10, 20, 50, 100]"
|
||
:page-size="hardwareSearch.limit"
|
||
layout="total, sizes, prev, pager, next, jumper"
|
||
:total="hardwareTotal">
|
||
</el-pagination>
|
||
</div>
|
||
</el-tab-pane>
|
||
|
||
<el-tab-pane label="AI模型/算法工具" name="ai">
|
||
<div class="table-actions">
|
||
<el-input
|
||
placeholder="搜索AI项目"
|
||
v-model="aiSearch.keyword"
|
||
clearable
|
||
style="width: 300px;"
|
||
>
|
||
<el-button slot="append" icon="el-icon-search"></el-button>
|
||
</el-input>
|
||
|
||
<div>
|
||
<el-button type="primary" icon="el-icon-plus" @click="showNewAIDialog">新建项目</el-button>
|
||
<el-button icon="el-icon-refresh" @click="refreshAIProjects">刷新</el-button>
|
||
</div>
|
||
</div>
|
||
|
||
<el-table :data="aiData" border style="width: 100%">
|
||
<el-table-column prop="name" label="项目名称" width="250"></el-table-column>
|
||
<el-table-column prop="type" label="项目类型" width="150">
|
||
<template slot-scope="scope">
|
||
<el-tag>{{ scope.row.type }}</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="manager" label="项目经理" width="120"></el-table-column>
|
||
<el-table-column prop="startDate" label="开始日期" width="150"></el-table-column>
|
||
<el-table-column prop="endDate" label="计划完成" width="150"></el-table-column>
|
||
<el-table-column prop="progress" label="进度" width="150">
|
||
<template slot-scope="scope">
|
||
<el-progress :percentage="scope.row.progress" :status="scope.row.progress === 100 ? 'success' : ''"></el-progress>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="操作" width="180">
|
||
<template slot-scope="scope">
|
||
<el-button size="mini" @click="viewAIProject(scope.row)">详情</el-button>
|
||
<el-button size="mini" type="primary" @click="editAIProject(scope.row)">编辑</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
|
||
<div class="pagination-container">
|
||
<el-pagination
|
||
@size-change="handleAISizeChange"
|
||
@current-change="handleAICurrentChange"
|
||
:current-page="aiSearch.page"
|
||
:page-sizes="[10, 20, 50, 100]"
|
||
:page-size="aiSearch.limit"
|
||
layout="total, sizes, prev, pager, next, jumper"
|
||
:total="aiTotal">
|
||
</el-pagination>
|
||
</div>
|
||
</el-tab-pane>
|
||
</el-tabs>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 项目合同管理 - 收入合同 -->
|
||
<div v-if="activeModule === 'income-contract'">
|
||
<h2 class="module-title">项目合同管理 - 收入合同</h2>
|
||
|
||
<div class="card-container">
|
||
<div class="table-actions">
|
||
<el-input
|
||
placeholder="搜索收入合同"
|
||
v-model="incomeContractSearch.keyword"
|
||
clearable
|
||
style="width: 300px;"
|
||
>
|
||
<el-button slot="append" icon="el-icon-search"></el-button>
|
||
</el-input>
|
||
|
||
<div>
|
||
<el-button type="primary" icon="el-icon-plus" @click="showNewIncomeContractDialog">新建合同</el-button>
|
||
<el-button icon="el-icon-refresh" @click="refreshIncomeContracts">刷新</el-button>
|
||
</div>
|
||
</div>
|
||
|
||
<el-table :data="incomeContractData" border style="width: 100%">
|
||
<el-table-column prop="code" label="合同编号" width="150"></el-table-column>
|
||
<el-table-column prop="name" label="合同名称" width="250"></el-table-column>
|
||
<el-table-column prop="client" label="客户名称" width="200"></el-table-column>
|
||
<el-table-column prop="amount" label="合同金额" width="150" align="right"></el-table-column>
|
||
<el-table-column prop="signDate" label="签订日期" width="150"></el-table-column>
|
||
<el-table-column prop="status" label="合同状态" width="150">
|
||
<template slot-scope="scope">
|
||
<el-tag :type="scope.row.status === '履行中' ? 'success' :
|
||
scope.row.status === '已完成' ? 'info' : 'warning'">
|
||
{{ scope.row.status }}
|
||
</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="操作" width="180">
|
||
<template slot-scope="scope">
|
||
<el-button size="mini" @click="viewIncomeContract(scope.row)">详情</el-button>
|
||
<el-button size="mini" type="primary" @click="editIncomeContract(scope.row)">编辑</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
|
||
<div class="pagination-container">
|
||
<el-pagination
|
||
@size-change="handleIncomeContractSizeChange"
|
||
@current-change="handleIncomeContractCurrentChange"
|
||
:current-page="incomeContractSearch.page"
|
||
:page-sizes="[10, 20, 50, 100]"
|
||
:page-size="incomeContractSearch.limit"
|
||
layout="total, sizes, prev, pager, next, jumper"
|
||
:total="incomeContractTotal">
|
||
</el-pagination>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 施工立项 -->
|
||
<div v-if="activeModule === 'construction'">
|
||
<h2 class="module-title">施工立项</h2>
|
||
|
||
<div class="card-container">
|
||
<el-alert
|
||
title="此功能已实现,请从导航菜单进入具体功能"
|
||
type="info"
|
||
show-icon
|
||
:closable="false"
|
||
>
|
||
</el-alert>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 组织实施管理 -->
|
||
<div v-if="activeModule === 'implementation'">
|
||
<h2 class="module-title">组织实施管理</h2>
|
||
|
||
<div class="card-container">
|
||
<el-alert
|
||
title="此功能已实现,请从导航菜单进入具体功能"
|
||
type="info"
|
||
show-icon
|
||
:closable="false"
|
||
>
|
||
</el-alert>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script src="https://cdn.jsdelivr.net/npm/echarts@5.3.2/dist/echarts.min.js"></script>
|
||
<script>
|
||
new Vue({
|
||
el: '#app',
|
||
data() {
|
||
return {
|
||
isCollapse: false,
|
||
activeModule: 'bidding',
|
||
|
||
// 招采业务
|
||
biddingTab: 'search',
|
||
biddingSearch: {
|
||
keyword: '',
|
||
page: 1,
|
||
limit: 10
|
||
},
|
||
biddingData: [
|
||
{
|
||
title: '某风电场2023年叶片检查服务采购项目',
|
||
publisher: '某风电有限公司',
|
||
budget: '120.00万元',
|
||
deadline: '2023-12-15 17:00',
|
||
source: '中国招标投标网',
|
||
status: '进行中',
|
||
location: '内蒙古自治区',
|
||
duration: '6个月',
|
||
scope: '风电场50台机组叶片检查服务',
|
||
qualification: '具备风电叶片检查资质',
|
||
docUrl: 'https://example.com/bidding-docs/123',
|
||
content: '<p>本项目为某风电场2023年叶片检查服务采购,包括但不限于:</p><ul><li>叶片外观检查</li><li>无损检测</li><li>缺陷记录与评估</li><li>检查报告编制</li></ul>'
|
||
},
|
||
// 更多数据...
|
||
],
|
||
biddingTotal: 20,
|
||
currentBidding: null,
|
||
biddingDetailVisible: false,
|
||
crawlerSettingsVisible: false,
|
||
crawlerSettings: {
|
||
frequency: 'daily',
|
||
keywords: ['风电', '叶片', '检查', '运维'],
|
||
platforms: ['中国招标投标公共服务平台', '各省市公共资源交易中心'],
|
||
autoNotify: true,
|
||
notifyMethods: ['站内消息', '电子邮件']
|
||
},
|
||
newKeyword: '',
|
||
|
||
// 投标响应
|
||
biddingResponseTab: 'projects',
|
||
biddingResponseSearch: {
|
||
keyword: '',
|
||
page: 1,
|
||
limit: 10
|
||
},
|
||
biddingResponseData: [
|
||
{
|
||
projectName: '某风电场2023年叶片检查服务采购项目',
|
||
publisher: '某风电有限公司',
|
||
budget: '120.00万元',
|
||
deadline: '2023-12-15 17:00',
|
||
status: '准备中',
|
||
progress: 30
|
||
},
|
||
// 更多数据...
|
||
],
|
||
biddingResponseTotal: 15,
|
||
documentSearch: {
|
||
keyword: '',
|
||
page: 1,
|
||
limit: 10
|
||
},
|
||
documentData: [
|
||
{
|
||
name: '某风电场叶片检查技术标书',
|
||
project: '某风电场2023年叶片检查',
|
||
type: '技术标',
|
||
version: '1.0',
|
||
updateTime: '2023-11-10 14:30',
|
||
status: '进行中'
|
||
},
|
||
// 更多数据...
|
||
],
|
||
documentTotal: 8,
|
||
quotationSearch: {
|
||
keyword: '',
|
||
page: 1,
|
||
limit: 10
|
||
},
|
||
quotationData: [
|
||
{
|
||
name: '某风电场叶片检查报价单',
|
||
project: '某风电场2023年叶片检查',
|
||
totalPrice: '1,080,000.00',
|
||
profitRate: 15,
|
||
updateTime: '2023-11-08 10:15',
|
||
status: '草稿'
|
||
},
|
||
// 更多数据...
|
||
],
|
||
quotationTotal: 5,
|
||
noticeSearch: {
|
||
keyword: '',
|
||
page: 1,
|
||
limit: 10
|
||
},
|
||
noticeData: [
|
||
{
|
||
projectName: '某风电场2022年叶片检查服务',
|
||
publisher: '某风电有限公司',
|
||
winningPrice: '980,000.00',
|
||
noticeDate: '2023-01-15',
|
||
status: '已签约'
|
||
},
|
||
// 更多数据...
|
||
],
|
||
noticeTotal: 3,
|
||
newBiddingDialogVisible: false,
|
||
newBiddingForm: {
|
||
projectName: '',
|
||
publisher: '',
|
||
budget: '',
|
||
deadline: '',
|
||
location: [],
|
||
projectType: '',
|
||
docUrl: '',
|
||
description: ''
|
||
},
|
||
biddingRules: {
|
||
projectName: [
|
||
{ required: true, message: '请输入项目名称', trigger: 'blur' }
|
||
],
|
||
publisher: [
|
||
{ required: true, message: '请输入招标单位', trigger: 'blur' }
|
||
]
|
||
},
|
||
locationOptions: [
|
||
{
|
||
value: '北京市',
|
||
label: '北京市',
|
||
children: [
|
||
{ value: '东城区', label: '东城区' },
|
||
// 更多区县...
|
||
]
|
||
},
|
||
// 更多省市...
|
||
],
|
||
biddingFileList: [],
|
||
|
||
// 市场营销
|
||
marketingTab: 'promotion',
|
||
marketingSubTab: 'activities',
|
||
activitySearch: {
|
||
keyword: '',
|
||
page: 1,
|
||
limit: 10
|
||
},
|
||
activityData: [
|
||
{
|
||
name: '2023年风电运维技术研讨会',
|
||
type: '会议',
|
||
startDate: '2023-10-15 09:00',
|
||
endDate: '2023-10-16 17:00',
|
||
budget: '50,000.00',
|
||
status: '已结束'
|
||
},
|
||
// 更多数据...
|
||
],
|
||
activityTotal: 12,
|
||
clientSearch: {
|
||
keyword: '',
|
||
page: 1,
|
||
limit: 10
|
||
},
|
||
clientData: [
|
||
{
|
||
name: '某风电集团有限公司',
|
||
industry: '风电',
|
||
contact: '张经理',
|
||
phone: '13800138000',
|
||
level: 'A',
|
||
lastContact: '2023-11-08'
|
||
},
|
||
// 更多数据...
|
||
],
|
||
clientTotal: 25,
|
||
effectDateRange: ['2023-01-01', '2023-12-31'],
|
||
effectData: {
|
||
newClients: 15,
|
||
opportunities: 8,
|
||
conversionRate: 35
|
||
},
|
||
pickerOptions: {
|
||
shortcuts: [{
|
||
text: '最近一周',
|
||
onClick(picker) {
|
||
const end = new Date();
|
||
const start = new Date();
|
||
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
|
||
picker.$emit('pick', [start, end]);
|
||
}
|
||
}, {
|
||
text: '最近一个月',
|
||
onClick(picker) {
|
||
const end = new Date();
|
||
const start = new Date();
|
||
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
|
||
picker.$emit('pick', [start, end]);
|
||
}
|
||
}, {
|
||
text: '最近三个月',
|
||
onClick(picker) {
|
||
const end = new Date();
|
||
const start = new Date();
|
||
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
|
||
picker.$emit('pick', [start, end]);
|
||
}
|
||
}]
|
||
},
|
||
agreementSearch: {
|
||
keyword: '',
|
||
page: 1,
|
||
limit: 10
|
||
},
|
||
agreementData: [
|
||
{
|
||
name: '某风电集团2023-2025年叶片检查框架协议',
|
||
client: '某风电集团有限公司',
|
||
startDate: '2023-01-01',
|
||
endDate: '2025-12-31',
|
||
amount: '5,000,000.00',
|
||
status: '有效'
|
||
},
|
||
// 更多数据...
|
||
],
|
||
agreementTotal: 5,
|
||
industryTab: 'competitors',
|
||
competitorSearch: {
|
||
keyword: '',
|
||
page: 1,
|
||
limit: 10
|
||
},
|
||
competitorData: [
|
||
{
|
||
name: '某风电技术服务有限公司',
|
||
strength: '叶片维修',
|
||
marketShare: 25,
|
||
recentProjects: '多个风场运维',
|
||
level: 4
|
||
},
|
||
// 更多数据...
|
||
],
|
||
competitorTotal: 8,
|
||
analysisYear: '2023',
|
||
strategySearch: {
|
||
keyword: '',
|
||
page: 1,
|
||
limit: 10
|
||
},
|
||
strategyData: [
|
||
{
|
||
name: '长期合作客户优惠',
|
||
target: '框架协议客户',
|
||
discount: '5-10',
|
||
conditions: '合同金额大于100万',
|
||
effectiveness: '高'
|
||
},
|
||
// 更多数据...
|
||
],
|
||
strategyTotal: 6,
|
||
|
||
// 自建项目
|
||
selfProjectTab: 'software',
|
||
softwareSearch: {
|
||
keyword: '',
|
||
page: 1,
|
||
limit: 10
|
||
},
|
||
softwareData: [
|
||
{
|
||
name: '风电叶片智能检查系统',
|
||
type: '管理平台',
|
||
manager: '张工程师',
|
||
startDate: '2023-01-15',
|
||
endDate: '2023-12-31',
|
||
progress: 75
|
||
},
|
||
// 更多数据...
|
||
],
|
||
softwareTotal: 3,
|
||
hardwareSearch: {
|
||
keyword: '',
|
||
page: 1,
|
||
limit: 10
|
||
},
|
||
hardwareData: [
|
||
{
|
||
name: '风电叶片检测设备',
|
||
type: '硬件设备',
|
||
manager: '李工程师',
|
||
startDate: '2023-03-01',
|
||
endDate: '2023-09-30',
|
||
progress: 90
|
||
},
|
||
// 更多数据...
|
||
],
|
||
hardwareTotal: 2,
|
||
aiSearch: {
|
||
keyword: '',
|
||
page: 1,
|
||
limit: 10
|
||
},
|
||
aiData: [
|
||
{
|
||
name: '叶片缺陷AI识别算法',
|
||
type: 'AI模型',
|
||
manager: '王工程师',
|
||
startDate: '2023-02-15',
|
||
endDate: '2023-08-31',
|
||
progress: 60
|
||
},
|
||
// 更多数据...
|
||
],
|
||
aiTotal: 4,
|
||
|
||
// 项目合同管理 - 收入合同
|
||
incomeContractSearch: {
|
||
keyword: '',
|
||
page: 1,
|
||
limit: 10
|
||
},
|
||
incomeContractData: [
|
||
{
|
||
code: 'HT2023001',
|
||
name: '某风电场叶片检查服务合同',
|
||
client: '某风电有限公司',
|
||
amount: '980,000.00',
|
||
signDate: '2023-01-20',
|
||
status: '履行中'
|
||
},
|
||
// 更多数据...
|
||
],
|
||
incomeContractTotal: 5
|
||
}
|
||
},
|
||
mounted() {
|
||
// 初始化图表
|
||
this.initCharts();
|
||
},
|
||
methods: {
|
||
toggleSidebar() {
|
||
this.isCollapse = !this.isCollapse;
|
||
},
|
||
switchModule(module) {
|
||
this.activeModule = module;
|
||
},
|
||
|
||
// 招采业务 - 信息检索
|
||
searchBiddingInfo() {
|
||
this.$message(`搜索招标信息: ${this.biddingSearch.keyword}`);
|
||
// 实际应用中这里应该调用API获取数据
|
||
},
|
||
refreshBiddingData() {
|
||
this.$message('刷新招标数据');
|
||
// 实际应用中这里应该调用API获取数据
|
||
},
|
||
exportBiddingData() {
|
||
this.$message('导出招标数据');
|
||
},
|
||
showCrawlerSettings() {
|
||
this.crawlerSettingsVisible = true;
|
||
},
|
||
viewBiddingDetail(row) {
|
||
this.currentBidding = row;
|
||
this.biddingDetailVisible = true;
|
||
},
|
||
markAsInterested(row) {
|
||
this.$confirm(`确定要关注招标项目 "${row.title}" 吗?`, '提示', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning'
|
||
}).then(() => {
|
||
this.$message({
|
||
type: 'success',
|
||
message: '已关注该项目!'
|
||
});
|
||
}).catch(() => {
|
||
this.$message({
|
||
type: 'info',
|
||
message: '已取消操作'
|
||
});
|
||
});
|
||
},
|
||
goToBiddingResponse() {
|
||
this.biddingTab = 'response';
|
||
},
|
||
addKeyword() {
|
||
if (this.newKeyword && !this.crawlerSettings.keywords.includes(this.newKeyword)) {
|
||
this.crawlerSettings.keywords.push(this.newKeyword);
|
||
this.newKeyword = '';
|
||
}
|
||
},
|
||
removeKeyword(tag) {
|
||
this.crawlerSettings.keywords = this.crawlerSettings.keywords.filter(item => item !== tag);
|
||
},
|
||
saveCrawlerSettings() {
|
||
this.$message.success('爬虫设置已保存');
|
||
this.crawlerSettingsVisible = false;
|
||
},
|
||
handleBiddingSizeChange(val) {
|
||
this.biddingSearch.limit = val;
|
||
this.refreshBiddingData();
|
||
},
|
||
handleBiddingCurrentChange(val) {
|
||
this.biddingSearch.page = val;
|
||
this.refreshBiddingData();
|
||
},
|
||
|
||
// 招采业务 - 投标响应
|
||
showNewBiddingDialog() {
|
||
this.newBiddingDialogVisible = true;
|
||
},
|
||
refreshBiddingResponse() {
|
||
this.$message('刷新投标响应数据');
|
||
// 实际应用中这里应该调用API获取数据
|
||
},
|
||
viewBiddingResponse(row) {
|
||
this.$message(`查看投标响应: ${row.projectName}`);
|
||
},
|
||
editBiddingResponse(row) {
|
||
this.$message(`编辑投标响应: ${row.projectName}`);
|
||
},
|
||
refreshDocuments() {
|
||
this.$message('刷新标书数据');
|
||
// 实际应用中这里应该调用API获取数据
|
||
},
|
||
viewDocument(row) {
|
||
this.$message(`查看标书: ${row.name}`);
|
||
},
|
||
editDocument(row) {
|
||
this.$message(`编辑标书: ${row.name}`);
|
||
},
|
||
generateDocument(row) {
|
||
this.$message(`生成标书: ${row.name}`);
|
||
},
|
||
refreshQuotations() {
|
||
this.$message('刷新报价数据');
|
||
// 实际应用中这里应该调用API获取数据
|
||
},
|
||
viewQuotation(row) {
|
||
this.$message(`查看报价: ${row.name}`);
|
||
},
|
||
editQuotation(row) {
|
||
this.$message(`编辑报价: ${row.name}`);
|
||
},
|
||
confirmQuotation(row) {
|
||
this.$confirm(`确定要确认报价 "${row.name}" 吗?`, '提示', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning'
|
||
}).then(() => {
|
||
row.status = '已确认';
|
||
this.$message({
|
||
type: 'success',
|
||
message: '报价已确认!'
|
||
});
|
||
}).catch(() => {
|
||
this.$message({
|
||
type: 'info',
|
||
message: '已取消操作'
|
||
});
|
||
});
|
||
},
|
||
refreshNotices() {
|
||
this.$message('刷新中标通知数据');
|
||
// 实际应用中这里应该调用API获取数据
|
||
},
|
||
exportNotices() {
|
||
this.$message('导出中标通知数据');
|
||
},
|
||
viewNotice(row) {
|
||
this.$message(`查看中标通知: ${row.projectName}`);
|
||
},
|
||
processNotice(row) {
|
||
this.$message(`处理中标通知: ${row.projectName}`);
|
||
},
|
||
handleBiddingFileChange(file, fileList) {
|
||
this.biddingFileList = fileList;
|
||
},
|
||
submitNewBidding() {
|
||
this.$refs.newBiddingForm.validate(valid => {
|
||
if (valid) {
|
||
this.$message.success('新建投标项目成功');
|
||
this.newBiddingDialogVisible = false;
|
||
this.refreshBiddingResponse();
|
||
} else {
|
||
return false;
|
||
}
|
||
});
|
||
},
|
||
handleBiddingResponseSizeChange(val) {
|
||
this.biddingResponseSearch.limit = val;
|
||
this.refreshBiddingResponse();
|
||
},
|
||
handleBiddingResponseCurrentChange(val) {
|
||
this.biddingResponseSearch.page = val;
|
||
this.refreshBiddingResponse();
|
||
},
|
||
handleDocumentSizeChange(val) {
|
||
this.documentSearch.limit = val;
|
||
this.refreshDocuments();
|
||
},
|
||
handleDocumentCurrentChange(val) {
|
||
this.documentSearch.page = val;
|
||
this.refreshDocuments();
|
||
},
|
||
handleQuotationSizeChange(val) {
|
||
this.quotationSearch.limit = val;
|
||
this.refreshQuotations();
|
||
},
|
||
handleQuotationCurrentChange(val) {
|
||
this.quotationSearch.page = val;
|
||
this.refreshQuotations();
|
||
},
|
||
handleNoticeSizeChange(val) {
|
||
this.noticeSearch.limit = val;
|
||
this.refreshNotices();
|
||
},
|
||
handleNoticeCurrentChange(val) {
|
||
this.noticeSearch.page = val;
|
||
this.refreshNotices();
|
||
},
|
||
|
||
// 市场营销 - 营销推广
|
||
showNewActivityDialog() {
|
||
this.$message('显示新建营销活动对话框');
|
||
},
|
||
refreshActivities() {
|
||
this.$message('刷新营销活动数据');
|
||
// 实际应用中这里应该调用API获取数据
|
||
},
|
||
viewActivity(row) {
|
||
this.$message(`查看营销活动: ${row.name}`);
|
||
},
|
||
editActivity(row) {
|
||
this.$message(`编辑营销活动: ${row.name}`);
|
||
},
|
||
showNewClientDialog() {
|
||
this.$message('显示新增客户对话框');
|
||
},
|
||
refreshClients() {
|
||
this.$message('刷新客户数据');
|
||
// 实际应用中这里应该调用API获取数据
|
||
},
|
||
viewClient(row) {
|
||
this.$message(`查看客户: ${row.name}`);
|
||
},
|
||
editClient(row) {
|
||
this.$message(`编辑客户: ${row.name}`);
|
||
},
|
||
loadEffectData() {
|
||
this.$message('加载营销效果数据');
|
||
// 实际应用中这里应该调用API获取数据
|
||
this.initEffectChart();
|
||
},
|
||
handleActivitySizeChange(val) {
|
||
this.activitySearch.limit = val;
|
||
this.refreshActivities();
|
||
},
|
||
handleActivityCurrentChange(val) {
|
||
this.activitySearch.page = val;
|
||
this.refreshActivities();
|
||
},
|
||
handleClientSizeChange(val) {
|
||
this.clientSearch.limit = val;
|
||
this.refreshClients();
|
||
},
|
||
handleClientCurrentChange(val) {
|
||
this.clientSearch.page = val;
|
||
this.refreshClients();
|
||
},
|
||
|
||
// 市场营销 - 框架协议
|
||
showNewAgreementDialog() {
|
||
this.$message('显示新建框架协议对话框');
|
||
},
|
||
refreshAgreements() {
|
||
this.$message('刷新框架协议数据');
|
||
// 实际应用中这里应该调用API获取数据
|
||
},
|
||
viewAgreement(row) {
|
||
this.$message(`查看框架协议: ${row.name}`);
|
||
},
|
||
editAgreement(row) {
|
||
this.$message(`编辑框架协议: ${row.name}`);
|
||
},
|
||
terminateAgreement(row) {
|
||
this.$confirm(`确定要终止框架协议 "${row.name}" 吗?`, '提示', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning'
|
||
}).then(() => {
|
||
row.status = '已终止';
|
||
this.$message({
|
||
type: 'success',
|
||
message: '协议已终止!'
|
||
});
|
||
}).catch(() => {
|
||
this.$message({
|
||
type: 'info',
|
||
message: '已取消操作'
|
||
});
|
||
});
|
||
},
|
||
handleAgreementSizeChange(val) {
|
||
this.agreementSearch.limit = val;
|
||
this.refreshAgreements();
|
||
},
|
||
handleAgreementCurrentChange(val) {
|
||
this.agreementSearch.page = val;
|
||
this.refreshAgreements();
|
||
},
|
||
|
||
// 市场营销 - 同行业务
|
||
showNewCompetitorDialog() {
|
||
this.$message('显示新增竞争对手对话框');
|
||
},
|
||
refreshCompetitors() {
|
||
this.$message('刷新竞争对手数据');
|
||
// 实际应用中这里应该调用API获取数据
|
||
},
|
||
viewCompetitor(row) {
|
||
this.$message(`查看竞争对手: ${row.name}`);
|
||
},
|
||
editCompetitor(row) {
|
||
this.$message(`编辑竞争对手: ${row.name}`);
|
||
},
|
||
loadAnalysisData() {
|
||
this.$message('加载市场分析数据');
|
||
// 实际应用中这里应该调用API获取数据
|
||
this.initMarketShareChart();
|
||
this.initPriceTrendChart();
|
||
},
|
||
showNewStrategyDialog() {
|
||
this.$message('显示新建议价策略对话框');
|
||
},
|
||
viewStrategy(row) {
|
||
this.$message(`查看议价策略: ${row.name}`);
|
||
},
|
||
editStrategy(row) {
|
||
this.$message(`编辑议价策略: ${row.name}`);
|
||
},
|
||
handleCompetitorSizeChange(val) {
|
||
this.competitorSearch.limit = val;
|
||
this.refreshCompetitors();
|
||
},
|
||
handleCompetitorCurrentChange(val) {
|
||
this.competitorSearch.page = val;
|
||
this.refreshCompetitors();
|
||
},
|
||
handleStrategySizeChange(val) {
|
||
this.strategySearch.limit = val;
|
||
// 实际应用中这里应该调用API获取数据
|
||
},
|
||
handleStrategyCurrentChange(val) {
|
||
this.strategySearch.page = val;
|
||
// 实际应用中这里应该调用API获取数据
|
||
},
|
||
|
||
// 自建项目 - 软件开发
|
||
showNewSoftwareDialog() {
|
||
this.$message('显示新建软件项目对话框');
|
||
},
|
||
refreshSoftwareProjects() {
|
||
this.$message('刷新软件项目数据');
|
||
// 实际应用中这里应该调用API获取数据
|
||
},
|
||
viewSoftwareProject(row) {
|
||
this.$message(`查看软件项目: ${row.name}`);
|
||
},
|
||
editSoftwareProject(row) {
|
||
this.$message(`编辑软件项目: ${row.name}`);
|
||
},
|
||
handleSoftwareSizeChange(val) {
|
||
this.softwareSearch.limit = val;
|
||
this.refreshSoftwareProjects();
|
||
},
|
||
handleSoftwareCurrentChange(val) {
|
||
this.softwareSearch.page = val;
|
||
this.refreshSoftwareProjects();
|
||
},
|
||
|
||
// 自建项目 - 硬件开发
|
||
showNewHardwareDialog() {
|
||
this.$message('显示新建硬件项目对话框');
|
||
},
|
||
refreshHardwareProjects() {
|
||
this.$message('刷新硬件项目数据');
|
||
// 实际应用中这里应该调用API获取数据
|
||
},
|
||
viewHardwareProject(row) {
|
||
this.$message(`查看硬件项目: ${row.name}`);
|
||
},
|
||
editHardwareProject(row) {
|
||
this.$message(`编辑硬件项目: ${row.name}`);
|
||
},
|
||
handleHardwareSizeChange(val) {
|
||
this.hardwareSearch.limit = val;
|
||
this.refreshHardwareProjects();
|
||
},
|
||
handleHardwareCurrentChange(val) {
|
||
this.hardwareSearch.page = val;
|
||
this.refreshHardwareProjects();
|
||
},
|
||
|
||
// 自建项目 - AI模型/算法工具
|
||
showNewAIDialog() {
|
||
this.$message('显示新建AI项目对话框');
|
||
},
|
||
refreshAIProjects() {
|
||
this.$message('刷新AI项目数据');
|
||
// 实际应用中这里应该调用API获取数据
|
||
},
|
||
viewAIProject(row) {
|
||
this.$message(`查看AI项目: ${row.name}`);
|
||
},
|
||
editAIProject(row) {
|
||
this.$message(`编辑AI项目: ${row.name}`);
|
||
},
|
||
handleAISizeChange(val) {
|
||
this.aiSearch.limit = val;
|
||
this.refreshAIProjects();
|
||
},
|
||
handleAICurrentChange(val) {
|
||
this.aiSearch.page = val;
|
||
this.refreshAIProjects();
|
||
},
|
||
|
||
// 项目合同管理 - 收入合同
|
||
showNewIncomeContractDialog() {
|
||
this.$message('显示新建收入合同对话框');
|
||
},
|
||
refreshIncomeContracts() {
|
||
this.$message('刷新收入合同数据');
|
||
// 实际应用中这里应该调用API获取数据
|
||
},
|
||
viewIncomeContract(row) {
|
||
this.$message(`查看收入合同: ${row.name}`);
|
||
},
|
||
editIncomeContract(row) {
|
||
this.$message(`编辑收入合同: ${row.name}`);
|
||
},
|
||
handleIncomeContractSizeChange(val) {
|
||
this.incomeContractSearch.limit = val;
|
||
this.refreshIncomeContracts();
|
||
},
|
||
handleIncomeContractCurrentChange(val) {
|
||
this.incomeContractSearch.page = val;
|
||
this.refreshIncomeContracts();
|
||
},
|
||
|
||
// 图表初始化
|
||
initCharts() {
|
||
// 初始化营销效果图表
|
||
this.initEffectChart();
|
||
|
||
// 初始化市场份额图表
|
||
this.initMarketShareChart();
|
||
|
||
// 初始化价格趋势图表
|
||
this.initPriceTrendChart();
|
||
},
|
||
initEffectChart() {
|
||
const chart = echarts.init(document.getElementById('effectChart'));
|
||
chart.setOption({
|
||
title: {
|
||
text: '营销活动效果趋势',
|
||
left: 'center'
|
||
},
|
||
tooltip: {
|
||
trigger: 'axis'
|
||
},
|
||
legend: {
|
||
data: ['新增客户', '商机数量', '转化率'],
|
||
bottom: 10
|
||
},
|
||
grid: {
|
||
left: '3%',
|
||
right: '4%',
|
||
bottom: '15%',
|
||
containLabel: true
|
||
},
|
||
xAxis: {
|
||
type: 'category',
|
||
boundaryGap: false,
|
||
data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
|
||
},
|
||
yAxis: [
|
||
{
|
||
type: 'value',
|
||
name: '数量',
|
||
position: 'left'
|
||
},
|
||
{
|
||
type: 'value',
|
||
name: '转化率(%)',
|
||
position: 'right',
|
||
max: 100
|
||
}
|
||
],
|
||
series: [
|
||
{
|
||
name: '新增客户',
|
||
type: 'line',
|
||
data: [5, 8, 10, 12, 15, 18, 20, 22, 25, 28, 30, 32],
|
||
smooth: true,
|
||
itemStyle: {
|
||
color: '#409EFF'
|
||
}
|
||
},
|
||
{
|
||
name: '商机数量',
|
||
type: 'line',
|
||
data: [2, 3, 5, 6, 8, 10, 12, 14, 16, 18, 20, 22],
|
||
smooth: true,
|
||
itemStyle: {
|
||
color: '#67C23A'
|
||
}
|
||
},
|
||
{
|
||
name: '转化率',
|
||
type: 'line',
|
||
yAxisIndex: 1,
|
||
data: [40, 38, 50, 50, 53, 56, 60, 64, 64, 64, 67, 69],
|
||
smooth: true,
|
||
itemStyle: {
|
||
color: '#E6A23C'
|
||
}
|
||
}
|
||
]
|
||
});
|
||
},
|
||
initMarketShareChart() {
|
||
const chart = echarts.init(document.getElementById('marketShareChart'));
|
||
chart.setOption({
|
||
title: {
|
||
text: '2023年风电叶片检查市场份额',
|
||
left: 'center'
|
||
},
|
||
tooltip: {
|
||
trigger: 'item',
|
||
formatter: '{a} <br/>{b}: {c} ({d}%)'
|
||
},
|
||
legend: {
|
||
orient: 'vertical',
|
||
left: 10,
|
||
data: ['我公司', '竞争对手A', '竞争对手B', '竞争对手C', '其他']
|
||
},
|
||
series: [
|
||
{
|
||
name: '市场份额',
|
||
type: 'pie',
|
||
radius: ['50%', '70%'],
|
||
avoidLabelOverlap: false,
|
||
label: {
|
||
show: false,
|
||
position: 'center'
|
||
},
|
||
emphasis: {
|
||
label: {
|
||
show: true,
|
||
fontSize: '18',
|
||
fontWeight: 'bold'
|
||
}
|
||
},
|
||
labelLine: {
|
||
show: false
|
||
},
|
||
data: [
|
||
{ value: 35, name: '我公司', itemStyle: { color: '#409EFF' } },
|
||
{ value: 25, name: '竞争对手A', itemStyle: { color: '#67C23A' } },
|
||
{ value: 20, name: '竞争对手B', itemStyle: { color: '#E6A23C' } },
|
||
{ value: 15, name: '竞争对手C', itemStyle: { color: '#F56C6C' } },
|
||
{ value: 5, name: '其他', itemStyle: { color: '#909399' } }
|
||
]
|
||
}
|
||
]
|
||
});
|
||
},
|
||
initPriceTrendChart() {
|
||
const chart = echarts.init(document.getElementById('priceTrendChart'));
|
||
chart.setOption({
|
||
title: {
|
||
text: '2023年风电叶片检查服务价格趋势',
|
||
left: 'center'
|
||
},
|
||
tooltip: {
|
||
trigger: 'axis'
|
||
},
|
||
legend: {
|
||
data: ['我公司报价', '行业平均价', '最低价'],
|
||
bottom: 10
|
||
},
|
||
grid: {
|
||
left: '3%',
|
||
right: '4%',
|
||
bottom: '15%',
|
||
containLabel: true
|
||
},
|
||
xAxis: {
|
||
type: 'category',
|
||
boundaryGap: false,
|
||
data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
|
||
},
|
||
yAxis: {
|
||
type: 'value',
|
||
name: '价格(万元/台)'
|
||
},
|
||
series: [
|
||
{
|
||
name: '我公司报价',
|
||
type: 'line',
|
||
data: [2.5, 2.6, 2.55, 2.4, 2.3, 2.2, 2.1, 2.0, 1.95, 1.9, 1.85, 1.8],
|
||
smooth: true,
|
||
itemStyle: {
|
||
color: '#409EFF'
|
||
}
|
||
},
|
||
{
|
||
name: '行业平均价',
|
||
type: 'line',
|
||
data: [2.8, 2.7, 2.65, 2.6, 2.5, 2.4, 2.3, 2.2, 2.1, 2.0, 1.95, 1.9],
|
||
smooth: true,
|
||
itemStyle: {
|
||
color: '#67C23A'
|
||
}
|
||
},
|
||
{
|
||
name: '最低价',
|
||
type: 'line',
|
||
data: [2.2, 2.1, 2.0, 1.9, 1.8, 1.7, 1.6, 1.55, 1.5, 1.45, 1.4, 1.35],
|
||
smooth: true,
|
||
itemStyle: {
|
||
color: '#F56C6C'
|
||
}
|
||
}
|
||
]
|
||
});
|
||
}
|
||
}
|
||
});
|
||
</script>
|
||
</body>
|
||
</html> |