You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1030 lines
30 KiB

<template>
<div class="container">
<!-- 顶部信息 -->
<div class="containertop">
<div class="topleft">
<img src="@/assets/images/detailsicon/1.png" alt="" />
<span>基本信息</span>
</div>
<div
class="topright"
v-if="action === 'fill' || !action || action === 'okay'"
>
<el-button
type="primary"
size="medium"
plain
v-if="action === 'fill' || !action || action === 'okay'"
style="
border: none;
background-color: rgba(43, 98, 241, 0.1);
color: #2b62f1;
"
@click="edit"
>
<img
src="@/assets/images/detailsicon/icon-bj@2x.png"
alt="编辑"
style="width: 0.6rem; height: 0.6rem; margin-right: 4px"
/>
编辑
</el-button>
<el-button
type="primary"
size="medium"
plain
v-if="checkRole(['admin', 'common', 'gov'])"
style="
border: none;
background-color: rgba(43, 98, 241, 0.1);
color: #2b62f1;
"
@click="handleExport"
>
<img
src="@/assets/images/detailsicon/icon-dc@2x.png"
alt="编辑"
style="width: 0.6rem; height: 0.6rem; margin-right: 4px"
/>
导出
</el-button>
</div>
</div>
<!-- 内容展示区 -->
<div class="content">
<div class="picturediv">
<!-- 图片展示 -->
<el-carousel :autoplay="false" height="26rem">
<el-carousel-item v-for="(url, index) in carouselImages" :key="index">
<img
:src="url"
alt="项目图片"
style="
width: 100%;
height: 100%;
object-fit: contain;
object-position: center;
"
/>
</el-carousel-item>
</el-carousel>
</div>
<div class="descriptionsdiv">
<el-descriptions class="margin-top" :column="3" border>
<el-descriptions-item>
<template slot="label">
<span style="color: red">*</span> 项目名称
</template>
{{ basicInfo.name }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<span style="color: red">*</span> 项目法人单位
</template>
{{ basicInfo.xmfrdwxz }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<span style="color: red">*</span> 项目法人单位性质
</template>
<dict-tag :options="dict.type.xmfrdwxz" :value="basicInfo.nature" />
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<span style="color: red">*</span> 施工单位
</template>
{{ basicInfo.sgdw }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<span style="color: red">*</span> 设计单位
</template>
{{ basicInfo.sjdw }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<span style="color: red">*</span> 总投资额(万元)
</template>
{{ basicInfo.ztze }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<span style="color: red">*</span> 所属功能区
</template>
<dict-tag :options="dict.type.ssgnq" :value="basicInfo.ssgnq" />
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<span style="color: red">*</span> 建设起止时间
</template>
{{ basicInfo.begainTime }} 至 {{ basicInfo.endTime }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<span style="color: red">*</span> 现状分类
</template>
<dict-tag :options="dict.type.xzfl" :value="basicInfo.xzfl" />
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<span style="color: red">*</span> 建设地点
</template>
{{ basicInfo.jsdd }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<span style="color: red">*</span> 重点发展产业
</template>
{{ basicInfo.prioritize }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<span style="color: red">*</span> 建设模式
</template>
<dict-tag :options="dict.type.jsms" :value="basicInfo.jsms" />
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<span style="color: red">*</span> 项目标签
</template>
{{ basicInfo.label }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<span style="color: red">*</span> 项目负责人
</template>
{{ basicInfo.projectLeader }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<span style="color: red">*</span> 联系方式
</template>
{{ basicInfo.phone }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<span style="color: red">*</span> 施工许可证发放时间
</template>
{{ basicInfo.issuingTime }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<span style="color: red">*</span> 竣工验收时间
</template>
{{ basicInfo.acceptanceTime }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<span style="color: red">*</span> 建设进度
</template>
{{ basicInfo.jsjd }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<span style="color: red">*</span> 统一社会信用代码
</template>
{{ basicInfo.tyshxydm }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<span style="color: red">*</span> 计划投资额(亿元)
</template>
{{ basicInfo.jhtze }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<span style="color: red">*</span> 所属产业目录
</template>
<dict-tag :options="dict.type.shangloumulu" :value="basicInfo.ml" />
</el-descriptions-item>
<el-descriptions-item :span="3">
<template slot="label">
<span style="color: red">*</span> 所属细分产业
</template>
<dict-tag :options="dict.type.bqlx" :value="basicInfo.xfcy" />
</el-descriptions-item>
<el-descriptions-item :span="3">
<template slot="label">
<span style="color: red">*</span> 项目法人单位简介
</template>
{{ basicInfo.unitIntroduction }}
</el-descriptions-item>
<el-descriptions-item :span="3">
<template slot="label">
<span style="color: red">*</span> 项目简介
</template>
{{ basicInfo.introduction }}
</el-descriptions-item>
</el-descriptions>
</div>
</div>
<!-- 添加或编辑项目对话框 -->
<el-dialog
:title="title"
:visible.sync="dialogVisible"
width="70rem"
append-to-body
>
<el-form :model="form" :rules="rules" ref="form" label-width="180px">
<el-row>
<el-col :span="12">
<el-form-item label="项目名称" prop="name">
<el-input
v-model="form.name"
maxlength="50"
placeholder="请输入项目名称"
></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="建设地点" prop="jsdd">
<el-row :gutter="10">
<el-col :span="20">
<el-input
v-model="form.jsdd"
maxlength="50"
placeholder="请点击右侧落图"
readonly
></el-input>
</el-col>
<el-col :span="3">
<span @click="showMap" style="color: #2b62f1; cursor: pointer"
>落图</span
>
</el-col>
</el-row>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="项目法人单位" prop="xmfrdwxz">
<el-input
v-model="form.xmfrdwxz"
maxlength="50"
placeholder="请输入项目法人单位"
></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="重点发展产业" prop="prioritize">
<el-input
v-model="form.prioritize"
maxlength="50"
placeholder="请输入重点发展产业"
></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="项目法人单位性质" prop="nature">
<el-select
v-model="form.nature"
placeholder="请选择"
value-key="value"
style="width: 100%"
>
<el-option
v-for="dict in dict.type.xmfrdwxz"
:key="dict.value"
:label="dict.label"
:value="parseInt(dict.value)"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="建设模式" prop="jsms">
<el-select
v-model="form.jsms"
placeholder="请选择"
value-key="value"
style="width: 100%"
>
<el-option
v-for="dict in dict.type.jsms"
:key="dict.value"
:label="dict.label"
:value="parseInt(dict.value)"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="施工单位" prop="sgdw">
<el-input
v-model="form.sgdw"
maxlength="50"
placeholder="请输入施工单位"
></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目标签" prop="label">
<el-input
v-model="form.label"
maxlength="50"
placeholder="请输入项目标签"
></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="设计单位" prop="sjdw">
<el-input
v-model="form.sjdw"
maxlength="50"
placeholder="请输入设计单位"
></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目负责人" prop="projectLeader">
<el-input
v-model="form.projectLeader"
maxlength="50"
placeholder="请输入项目负责人"
></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="总投资额(万元)" prop="ztze">
<el-input
v-model.number="form.ztze"
maxlength="50"
placeholder="请输入总投资额"
></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="联系方式" prop="phone">
<el-input
v-model="form.phone"
maxlength="50"
placeholder="请输入联系方式"
></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="所属功能区" prop="ssgnq">
<el-select
v-model="form.ssgnq"
placeholder="请选择"
value-key="value"
style="width: 100%"
>
<el-option
v-for="dict in dict.type.ssgnq"
:key="dict.value"
:label="dict.label"
:value="parseInt(dict.value)"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="施工许可证发放时间" prop="issuingTime">
<el-input
v-model="form.issuingTime"
maxlength="50"
placeholder="请输入施工许可证发放时间"
></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="建设起止时间" required>
<el-date-picker
v-model="form.begainTime"
type="month"
value-format="yyyy-MM"
placeholder="开始日期"
style="width: 11rem"
></el-date-picker>
~
<el-date-picker
v-model="form.endTime"
type="month"
value-format="yyyy-MM"
placeholder="结束日期"
style="width: 10.5rem"
></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="竣工验收时间" prop="acceptanceTime">
<el-input
v-model="form.acceptanceTime"
maxlength="50"
placeholder="请输入竣工验收时间"
></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="现状分类" prop="xzfl">
<el-select
v-model="form.xzfl"
placeholder="请选择"
value-key="value"
style="width: 100%"
>
<el-option
v-for="dict in dict.type.xzfl"
:key="dict.value"
:label="dict.label"
:value="parseInt(dict.value)"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="建设进度" prop="jsjd">
<el-input
v-model="form.jsjd"
maxlength="50"
placeholder="请输入建设进度"
></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="统一社会信用代码" prop="tyshxydm">
<el-input
v-model="form.tyshxydm"
maxlength="50"
placeholder="请输入统一社会信用代码"
></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="计划投资额(亿元)" prop="jhtze">
<el-input
v-model="form.jhtze"
maxlength="50"
placeholder="请输入计划投资额(亿元)"
></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="所属产业目录" prop="ml">
<el-select
v-model="form.ml"
placeholder="请选择产业目录"
value-key="value"
style="width: 100%"
>
<el-option
v-for="dict in dict.type.shangloumulu"
:key="dict.value"
:label="dict.label"
:value="parseInt(dict.value)"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="所属细分产业" prop="xfcy">
<el-select
v-model="form.xfcy"
placeholder="请选择所属细分产业"
value-key="value"
style="width: 100%"
>
<el-option
v-for="dict in dict.type.bqlx"
:key="dict.value"
:label="dict.label"
:value="parseInt(dict.value)"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row style="display: none">
<el-col :span="12">
<el-form-item label="经度" prop="longitude">
<el-input v-model="form.longitude" maxlength="50"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="纬度" prop="latitude">
<el-input v-model="form.latitude" maxlength="50"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="项目法人单位简介" prop="unitIntroduction">
<el-input
v-model="form.unitIntroduction"
type="textarea"
rows="4"
maxlength="1000"
placeholder="请输入项目法人单位简介"
></el-input>
</el-form-item>
<el-form-item label="项目简介" prop="introduction">
<el-input
v-model="form.introduction"
type="textarea"
rows="4"
maxlength="1000"
placeholder="请输入项目简介"
></el-input>
</el-form-item>
<el-form-item label="项目代表性照片" prop="fj">
<ImageUpload v-model="form.fj" />
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="saveForm"> </el-button>
</span>
</el-dialog>
<!-- 地图弹窗 -->
<el-dialog
:title="mapDialogTitle"
:visible.sync="mapDialogVisible"
width="1000px"
append-to-body
>
<luotu v-if="mapDialogVisible" @confirm-selection="handleMapConfirm" />
</el-dialog>
</div>
</template>
<script>
import ImageUpload from "@/components/ImageUpload2/index.vue";
import luotu from "@/views/components/ProjectDetails/luotu.vue";
import { checkPermi, checkRole } from "@/utils/permission";
export default {
components: {
ImageUpload,
luotu,
},
dicts: [
"ssgnq",
"xmfrdwxz",
"xzfl",
"jsms",
"shangloumulu",
"bqlxbqlx",
"bqlx",
],
props: {
size: {
type: String,
default: "",
},
basicInfo: {
type: Object,
required: true,
},
action: {
type: String,
required: true,
},
},
data() {
return {
baseUrl: process.env.VUE_APP_BASE_API,
descriptions: [],
dialogImageUrl: "",
dialogVisibletwo: false,
dialogVisible: false,
mapDialogVisible: false,
mapDialogTitle: "地图",
title: "编辑基本信息",
form: {
name: "",
xmfrdwxz: "",
nature: 0,
sgdw: "",
sjdw: "",
ztze: 0,
id: 0,
ssgnq: 0,
begainTime: "",
endtime: "",
xzfl: 0,
jsdd: "",
prioritize: "",
jsms: 0,
label: "",
projectLeader: "",
phone: "",
issuingTime: "",
acceptanceTime: "",
unitIntroduction: "",
introduction: "",
fj: "",
jsjd: "",
// 经度
longitude: "",
//纬度
latitude: "",
},
rules: {
name: [
{ required: true, message: "项目名称不能为空", trigger: "blur" },
],
xmfrdwxz: [
{ required: true, message: "项目法人单位不能为空", trigger: "blur" },
],
nature: [
{
required: true,
message: "项目法人单位性质不能为空",
trigger: "change",
},
],
sgdw: [
{ required: true, message: "施工单位不能为空", trigger: "blur" },
],
sjdw: [
{ required: true, message: "设计单位不能为空", trigger: "blur" },
],
ztze: [
{ required: true, message: "总投资额不能为空", trigger: "blur" },
{ type: "number", message: "总投资额必须是数字", trigger: "blur" },
],
ssgnq: [
{ required: true, message: "所属功能区不能为空", trigger: "change" },
],
begainTime: [
{
required: true,
message: "建设起始时间不能为空",
trigger: "change",
},
],
endTime: [
{
required: true,
message: "建设结束时间不能为空",
trigger: "change",
},
],
xzfl: [
{ required: true, message: "现状分类不能为空", trigger: "change" },
],
jsdd: [
{ required: true, message: "建设地点不能为空", trigger: "blur" },
],
prioritize: [
{ required: true, message: "重点发展产业不能为空", trigger: "blur" },
],
jsms: [
{ required: true, message: "建设模式不能为空", trigger: "change" },
],
label: [
{ required: true, message: "项目标签不能为空", trigger: "blur" },
],
projectLeader: [
{ required: true, message: "项目负责人不能为空", trigger: "blur" },
],
phone: [
{ required: true, message: "联系方式不能为空", trigger: "blur" },
{
pattern: /^[\d-]+$/,
message: "联系方式只能包含数字和连字符",
trigger: "blur",
},
],
issuingTime: [
{
required: true,
message: "施工许可证发放时间不能为空",
trigger: "blur",
},
],
acceptanceTime: [
{ required: true, message: "竣工验收时间不能为空", trigger: "blur" },
],
jsjd: [
{ required: true, message: "建设进度不能为空", trigger: "blur" },
],
tyshxydm: [
{
required: true,
message: "统一社会信用代码不能为空",
trigger: "blur",
},
{
pattern: /^[a-zA-Z0-9]{18}$/,
message: "请输入正确格式的18位统一社会信用代码",
trigger: "blur",
},
],
jhtze: [
{
required: true,
message: "计划投资额(亿元)不能为空",
trigger: "blur",
},
],
ml: [
{
required: true,
message: "所属产业目录不能为空",
trigger: "change",
},
],
xfcy: [
{
required: true,
message: "所属细分产业不能为空",
trigger: "change",
},
],
unitIntroduction: [
{
required: true,
max: 1000,
message: "项目法人单位简介长度不能超过1000个字",
trigger: "blur",
},
],
introduction: [
{
required: true,
max: 1000,
message: "项目简介长度不能超过1000个字",
trigger: "blur",
},
],
fj: [
{
required: true,
message: "请上传至少一张项目代表性照片",
trigger: "change",
},
{
validator: (rule, value, callback) => {
if (
!value ||
value.split(",").filter((url) => url.trim() !== "").length === 0
) {
callback(new Error("请上传至少一张项目代表性照片"));
} else {
callback();
}
},
trigger: "change",
},
],
},
};
},
watch: {
basicInfo: {
handler(newVal) {
// 处理图片轮播数据
if (newVal.fj) {
this.carouselImages = newVal.fj
.split(",")
.map((url) => this.baseUrl + url.trim());
} else {
this.carouselImages = [];
}
// 设置表单数据
this.form = {
...newVal,
begainTime: newVal.begainTime ? new Date(newVal.begainTime) : "",
endTime: newVal.endTime ? new Date(newVal.endTime) : "",
};
},
immediate: true,
deep: true,
},
},
methods: {
checkPermi,
checkRole,
// 添加处理地图选择的方法
handleMapConfirm(location) {
this.form.jsdd = location.address; // 设置建设地点
this.form.longitude = location.lng; // 设置经度
this.form.latitude = location.lat; // 设置纬度
this.mapDialogVisible = false; // 关闭地图弹窗
},
/* 导出按钮操作 */
handleExport() {
this.download(
"/gysl/basicInformation/export",
{
xmid: this.basicInfo.id,
},
`基本信息导出${new Date().getTime()}.xlsx`
);
},
// 打开编辑对话框
edit() {
this.dialogVisible = true;
},
// 保存表单
saveForm() {
if (this.validateForm()) {
const formData = this.prepareFormData(this.form);
// 触发事件,将数据传递给父组件
this.$emit("update-data", formData);
this.dialogVisible = false;
}
},
// 手动验证表单
validateForm() {
for (const field in this.rules) {
const rules = this.rules[field];
const value = this.form[field];
for (const rule of rules) {
if (rule.required && !value) {
this.$message.error(rule.message);
return false;
}
}
}
return true;
},
// 准备表单数据
prepareFormData(formData) {
// 格式化日期字段
const formatDate = (date) => {
if (!date) return "";
// 如果是 Date 对象,直接格式化;如果是字符串,保持原样
return date instanceof Date ? date.toISOString().split("T")[0] : date;
};
return {
...formData,
begainTime: formatDate(formData.begainTime), // 单独格式化 begainTime
endTime: formatDate(formData.endTime),
createBy: "",
createId: 0,
createTime: "",
updateBy: "",
updateId: 0,
updateTime: "",
};
},
// formatDateRange(dateRange) {
// if (!dateRange || dateRange.length !== 2) return ['', '']; // 防止空值报错
// // 格式化日期,确保返回 YYYY-MM-DD 格式
// const formatDate = (date) => {
// if (!date) return '';
// // 如果是 Date 对象,直接格式化;如果是字符串,先转成 Date 再格式化
// const d = date instanceof Date ? date : new Date(date);
// return d.toISOString().split('T')[0]; // 取 YYYY-MM-DD 部分
// };
// return [
// formatDate(dateRange[0]), // 开始日期
// formatDate(dateRange[1]) // 结束日期
// ];
// },
// 处理附件上传成功
handleAttachmentSuccess(response, file) {
this.form.fj = response.url;
},
// 上传前验证
beforeAttachmentUpload(file) {
const isImage = file.type.startsWith("image/");
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isImage) this.$message.error("只能上传图片文件!");
if (!isLt2M) this.$message.error("上传图片大小不能超过 2MB!");
return isImage && isLt2M;
},
// 删除附件
removeAttachment() {
this.form.fj = "";
},
// 显示地图弹窗
showMap() {
this.mapDialogVisible = true;
},
},
};
</script>
<style scoped>
.container {
display: flex;
flex-direction: column;
width: 100%;
background-color: #ffffff;
box-shadow: 0rem 0.13rem 0.63rem 0rem rgba(177, 177, 177, 0.1);
border-radius: 0.5rem 0.5rem 0.5rem 0.5rem;
}
.content {
padding: 1rem;
display: flex;
}
.containertop {
height: auto;
display: flex;
justify-content: space-between;
padding: 0.5rem;
border-bottom: 1px solid #e5e5e5;
}
.topleft {
height: 2rem;
width: 8rem;
display: flex;
gap: 0.4rem;
align-items: center;
}
.topleft img {
width: 0.81rem;
height: 0.81rem;
}
.topleft span {
width: auto;
height: 1rem;
font-family: aliregular;
font-weight: 500;
font-size: 1rem;
color: #3d424c;
line-height: 1rem;
text-align: right;
font-style: normal;
text-transform: none;
}
.picturediv {
width: 24.4rem;
height: 26rem;
position: relative;
overflow: hidden;
}
.picturediv img {
width: 100%;
height: auto;
object-fit: cover;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
}
.descriptionsdiv {
width: calc(100% - 25rem);
margin-left: 1rem;
height: auto;
}
.two-row-item {
height: auto;
}
.tanchuang {
width: 70rem;
height: auto;
padding: 2rem;
}
</style>