增加招投标模块

This commit is contained in:
2026-09-24 17:06:46 +08:00
parent bc9e32d62a
commit eafa5e1cf4
51 changed files with 13453 additions and 5 deletions
@@ -0,0 +1,145 @@
<template>
<div class="bid-basic" v-loading="loading">
<div class="section-header">
<h3 class="section-title">基本信息</h3>
<div class="section-actions">
<el-button v-if="canEdit" type="primary" link :icon="EditPen" @click="handleEdit">编辑</el-button>
<el-button v-if="canConvertContract" type="success" link :icon="Document" @click="handleConvert('contract')">
中标转合同
</el-button>
<el-button v-if="canConvertProject" type="warning" link :icon="Box" @click="handleConvert('project')">
中标转项目
</el-button>
</div>
</div>
<el-descriptions :column="2" border>
<el-descriptions-item label="投标编号">{{ bid.bid_no || "-" }}</el-descriptions-item>
<el-descriptions-item label="投标标题">{{ bid.title }}</el-descriptions-item>
<el-descriptions-item label="投标类型">
<el-tag size="small">{{ bidTypeText(bid.bid_type) }}</el-tag>
</el-descriptions-item>
<el-descriptions-item label="投标状态">
<el-tag :type="bidStatusTag(bid.status)" size="small">
{{ bidStatusText(bid.status) }}
</el-tag>
</el-descriptions-item>
<el-descriptions-item label="来源">
<el-tag v-if="bid.source_type === 1" size="small" type="warning">商机</el-tag>
<el-tag v-else-if="bid.source_type === 2" size="small" type="primary">项目</el-tag>
<el-tag v-else size="small" type="info" effect="plain">独立</el-tag>
</el-descriptions-item>
<el-descriptions-item label="来源名称">
<span v-if="bid.business_name">{{ bid.business_name }}</span>
<span v-else-if="bid.project_name">{{ bid.project_name }}</span>
<span v-else>-</span>
</el-descriptions-item>
<el-descriptions-item label="招标方">{{ bid.customer_name || "-" }}</el-descriptions-item>
<el-descriptions-item label="发布单位">{{ bid.publish_org || "-" }}</el-descriptions-item>
<el-descriptions-item label="投标报价">{{ formatMoney(bid.bid_amount) }}</el-descriptions-item>
<el-descriptions-item label="保证金">{{ formatMoney(bid.bid_deposit) }}</el-descriptions-item>
<el-descriptions-item label="招标发布日期">{{ formatDateOnly(bid.publish_date) }}</el-descriptions-item>
<el-descriptions-item label="报名截止">{{ formatDateTime(bid.register_end_date) }}</el-descriptions-item>
<el-descriptions-item label="投标截止">{{ formatDateTime(bid.bid_end_date) }}</el-descriptions-item>
<el-descriptions-item label="开标时间">{{ formatDateTime(bid.open_bid_date) }}</el-descriptions-item>
<el-descriptions-item label="中标状态">
<el-tag v-if="bid.win_status === 1" type="success" size="small">已中标</el-tag>
<el-tag v-else-if="bid.win_status === 2" type="danger" size="small">未中标</el-tag>
<el-tag v-else-if="bid.win_status === 3" type="warning" size="small">废标</el-tag>
<el-tag v-else-if="bid.win_status === 4" type="info" size="small">流标</el-tag>
<el-tag v-else type="info" size="small" effect="plain">未开标</el-tag>
</el-descriptions-item>
<el-descriptions-item label="中标日期">{{ formatDateTime(bid.win_date) }}</el-descriptions-item>
<el-descriptions-item label="我方排名">{{ bid.our_ranking || "-" }}</el-descriptions-item>
<el-descriptions-item label="我方得分">{{ bid.total_score || "-" }}</el-descriptions-item>
<el-descriptions-item label="联系人">{{ bid.contact_person || "-" }}</el-descriptions-item>
<el-descriptions-item label="联系电话">{{ bid.contact_phone || "-" }}</el-descriptions-item>
<el-descriptions-item label="负责人">{{ bid.owner_user_name || "-" }}</el-descriptions-item>
<el-descriptions-item label="创建时间">{{ formatDateTime(bid.create_time) }}</el-descriptions-item>
<el-descriptions-item label="关联合同">
<el-link v-if="bid.contract_id" type="primary" :underline="false">合同 #{{ bid.contract_id }}</el-link>
<span v-else>-</span>
</el-descriptions-item>
<el-descriptions-item label="关联项目" v-if="bid.new_project_id || bid.project_id">
<el-link type="primary" :underline="false">
项目 #{{ bid.new_project_id || bid.project_id }}
</el-link>
</el-descriptions-item>
</el-descriptions>
<el-divider />
<h4 class="block-title">项目描述</h4>
<div class="content-box">{{ bid.description || "暂无描述" }}</div>
<h4 class="block-title">备注</h4>
<div class="content-box">{{ bid.remark || "—" }}</div>
</div>
</template>
<script setup>
import { computed, ref } from "vue";
import { EditPen, Document, Box } from "@element-plus/icons-vue";
import {
bidStatusText,
bidStatusTag,
bidTypeText,
formatMoney,
formatDateOnly,
formatDateTime,
} from "@/views/apps/crm/dict";
const props = defineProps({
bid: { type: Object, required: true },
});
const emit = defineEmits(["action"]);
const loading = ref(false);
const canEdit = computed(() => props.bid.locked !== 1 && props.bid.status !== 6);
const canConvertContract = computed(
() => props.bid.win_status === 1 && !props.bid.contract_id
);
const canConvertProject = computed(
() => props.bid.win_status === 1 && !props.bid.new_project_id
);
function handleEdit() {
emit("action", { type: "edit", row: props.bid });
}
function handleConvert(type) {
emit("action", { type, row: props.bid });
}
</script>
<style scoped>
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16px;
}
.section-title {
margin: 0;
font-size: 16px;
font-weight: 600;
}
.block-title {
margin: 16px 0 8px;
font-size: 14px;
font-weight: 500;
color: var(--el-text-color-regular);
}
.content-box {
background: var(--el-bg-color-page);
border-radius: 6px;
padding: 12px;
font-size: 13px;
line-height: 1.6;
color: var(--el-text-color-primary);
min-height: 40px;
white-space: pre-wrap;
word-break: break-word;
}
</style>