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.

716 lines
19 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="bigone">
<!-- 标题和目录 -->
<xiding>
<div style="padding: 0 0.9rem 0 0.5rem">
<div class="containerheadone" id="listtop">
<Title :basicInfo="basicInformation"></Title>
<el-button
type="primary"
size="medium"
plain
style="
border: none;
background-color: rgba(43, 98, 241, 0.1);
color: #2b62f1;
"
@click="goBack"
>
返回
</el-button>
</div>
<!-- 目录 -->
<div class="containerhead">
<el-menu
:default-active="activeSection"
mode="horizontal"
@select="scrollToSection"
ref="menuRef"
class="custom-menu"
@click="handleMenuClick"
@mousedown.native.prevent
>
<el-menu-item
v-for="(item, index) in sections"
:key="index"
:index="item.id"
class="custom-menu-item"
>
{{ item.label }}
</el-menu-item>
</el-menu>
</div>
</div>
</xiding>
<div class="containerbody" v-if="isContainerVisible" @scroll="handleScroll">
<!-- 基本信息 -->
<div id="basic">
<Basic
:action="action"
:basicInfo="basicInformation"
@update-data="handleDataUpdate('basicInformation', $event)"
>
</Basic>
</div>
<!-- 规划信息 -->
<div id="programme">
<Programme
:action="action"
:planInfo="planInformation"
:xmId="projectId"
@update-data="handleDataUpdate('planInformation', $event)"
>
</Programme>
</div>
<!-- 建筑信息 -->
<div id="buildings">
<Buildings
:action="action"
:xmId="projectId"
@has-building-data="hasBuildingData = $event"
></Buildings>
</div>
<!-- 要素模型信息 -->
<div id="models">
<Models
:action="action"
:wysmxInfo="wysmxInformations"
@updata-data="handleDataUpdate('wysmxInformations', $event)"
>
</Models>
</div>
<!-- 月度进展信息 -->
<div id="months">
<Months :action="action" :xmId="projectId"></Months>
</div>
<!-- 企业入驻信息 -->
<div id="companyenter">
<Companyenter
:xmId="projectId"
:action="action"
:qyrzInfo="qyrzInformation"
@update-data="handleDataUpdate('qyrzInformation', $event)"
>
</Companyenter>
</div>
<!-- 项目画像 -->
<div id="projectpicture">
<Projectpicture :action="action" :id="projectId"></Projectpicture>
</div>
<!-- 项目图例 -->
<div id="projectpicturetwo">
<Projectdraw :action="action" :xmId="projectId"> </Projectdraw>
</div>
<!-- 项目巡礼 -->
<div id="projectgift">
<Projectgift :action="action" :xmId="projectId"></Projectgift>
</div>
<!-- 现场实况 -->
<div id="liver">
<Liver :action="action"></Liver>
</div>
<!-- 项目备忘录 -->
<div id="memo">
<Memo :action="action" :xmId="projectId"></Memo>
</div>
<!-- -->
<div class="bottombox" id="others">
<Others
:action="action"
:xmId="projectId"
:anotherInfo="projectOtherInfos"
@refresh-data="fetchOtherInfo"
@update-data="handleDataUpdate('projectOtherInfos', $event)"
>
</Others>
</div>
<div class="footer">
<el-button
type="primary"
v-if="
(checkRole(['company']) && !isSubmitted && action === 'fill') ||
action === 'fill'
"
@click="submitAll"
>提交审核</el-button
>
<el-button
type="primary"
v-if="
(checkRole(['company']) && !isSubmitted && action === 'fill') ||
action === 'fill'
"
@click="saveAll"
>暂存</el-button
>
</div>
</div>
<!-- 返回顶部 -->
<el-backtop
target=".containerbody"
:visibility-height="200"
:bottom="50"
:right="10"
style="z-index: 1000"
>
</el-backtop>
</div>
</template>
<script>
import xiding from "./index2.vue";
import Title from "@/views/components/ProjectDetails/Title.vue";
import Basic from "@/views/components/ProjectDetails/Basic.vue";
import Buildings from "@/views/components/ProjectDetails/Buildings.vue";
import Companyenter from "@/views/components/ProjectDetails/Companyenter.vue";
import Liver from "@/views/components/ProjectDetails/Liver.vue";
import Memo from "@/views/components/ProjectDetails/Memo.vue";
import Models from "@/views/components/ProjectDetails/Models.vue";
import Months from "@/views/components/ProjectDetails/Months.vue";
import Programme from "@/views/components/ProjectDetails/Programme.vue";
import Projectgift from "@/views/components/ProjectDetails/Projectgift.vue";
import Projectpicture from "@/views/components/ProjectDetails/Projectpicture.vue";
import Projectdraw from "@/views/components/ProjectDetails/Projectdraw.vue";
import Others from "@/views/components/ProjectDetails/Others.vue";
import { checkPermi, checkRole } from "@/utils/permission";
import {
getBasicInformationById,
fillBasicInformation,
auditBasicInformation,
tempBasicInformation,
getqyBasicInformationPage,
} from "@/api/ManageApi/index";
export default {
components: {
Title,
Basic,
Buildings,
Companyenter,
Liver,
Memo,
Models,
Months,
Programme,
Projectgift,
Projectpicture,
Projectdraw,
Others,
xiding,
},
data() {
return {
hasBuildingData: false,
activeSection: "basic",
sections: [
{ id: "basic", label: "基本信息" },
{ id: "programme", label: "规划信息" },
{ id: "buildings", label: "建筑信息" },
{ id: "models", label: "五要素模型信息" },
{ id: "months", label: "月度进展信息" },
{ id: "companyenter", label: "企业入驻信息" },
{ id: "projectpicture", label: "项目画像" },
{ id: "projectpicturetwo", label: "项目图例" },
{ id: "projectgift", label: "项目巡礼" },
{ id: "liver", label: "现场实况" },
{ id: "memo", label: "项目备忘录" },
{ id: "others", label: "其他信息" },
],
projectId: null,
isContainerVisible: true,
isSubmitted: false,
lastScrollTop: 0,
scrollDirection: "down",
scrollTimeout: null,
basicInformation: {
acceptanceTime: "",
begainTime: "",
endTime: "",
fj: "",
introduction: "",
issuingTime: "",
jsdd: "",
jsjd: "",
jsms: 0,
label: "",
latitude: "",
longitude: "",
name: "",
nature: 0,
id: 0,
phone: "",
prioritize: "",
projectLeader: "",
sgdw: "",
sjdw: "",
ssgnq: 0,
status: 0,
tyshxydm: "",
unitIntroduction: "",
xmfrdwxz: "",
xzfl: 0,
zjzmj: 0,
ztze: 0,
zydmj: 0,
},
planInformation: {
bzcjzmj: 0,
dsjzmj: 0,
dxjzmj: 0,
fhdj: "",
fjdctcw: 0,
ghwj: "",
jdctcw: 0,
jrjljzmj: 0,
jzds: 0,
jzmd: 0,
ldl: 0,
id: 0,
rjl: 0,
xmId: 0,
zgjzcs: 0,
zgjzgd: 0,
zjzmj: 0,
zydmj: 0,
},
projectOtherInfos: [],
wysmxInformations: [],
qyrzInformation: {
gycfpjwyf: 0,
gycfpjzj: 0,
kzczmj: 0,
params: {},
remark: "",
rysl: 0,
id: 0,
rzl: 0,
rzqyhylx: "",
rzqys: 0,
xmId: 0,
yczmj: 0,
},
projectRemarks: [],
loading: false,
scrollTimeout: null,
};
},
created() {
this.projectId = Number(this.$route.params.id);
this.loadData();
this.action = this.$route.query.action;
this.loadData();
// 添加滚动监听
window.addEventListener("scroll", this.handleScroll);
const container = document.querySelector(".containerbody");
if (container) {
container.addEventListener("scroll", this.handleScroll);
}
},
beforeDestroy() {
window.removeEventListener("scroll", this.handleScroll);
const container = document.querySelector(".containerbody");
if (container) {
container.removeEventListener("scroll", this.handleScroll);
}
},
methods: {
async fetchOtherInfo() {
try {
const response = await getzwBasicInformationById(this.projectId);
const data = response.data;
// 从已有接口中提取 projectOtherInfos
this.projectOtherInfos = data.projectOtherInfos || [];
// this.$message.success("其他信息刷新成功");
} catch (error) {
console.error("获取其他信息失败", error);
this.$message.error("获取其他信息失败");
}
},
checkPermi,
checkRole,
loadData() {
this.loading = true;
getBasicInformationById(this.projectId)
.then((response) => {
const data = response.data;
this.basicInformation = data.basicInformation;
this.planInformation = data.planInformation;
this.projectOtherInfos = data.projectOtherInfos;
this.wysmxInformations = data.wysmxResponses;
this.qyrzInformation = data.qyrzInformation;
this.projectRemarks = data.projectRemarks;
})
.finally(() => {
this.loading = false;
});
},
scrollToSection(id) {
this.activeSection = id;
const element = document.getElementById(id);
if (element) {
element.scrollIntoView({ behavior: "smooth" });
this.$nextTick(() => {
// 移除菜单项焦点设置代码,仅设置内容区域焦点
element.focus();
});
}
},
scrollToTop() {
const basicSection = document.getElementById("listtop");
if (basicSection) {
basicSection.scrollIntoView({ behavior: "smooth" });
}
},
goBack() {
this.$router.go(-1);
},
handleScroll() {
const container = document.querySelector(".containerbody");
if (!container) return;
if (this.scrollTimeout) {
clearTimeout(this.scrollTimeout);
}
this.scrollTimeout = setTimeout(() => {
const scrollPosition = container.scrollTop;
if (scrollPosition > this.lastScrollTop) {
this.scrollDirection = "down";
} else {
this.scrollDirection = "up";
}
this.lastScrollTop = scrollPosition;
const offset = this.scrollDirection === "down" ? 500 : 200;
const adjustedScrollPosition = scrollPosition + offset;
for (let i = this.sections.length - 1; i >= 0; i--) {
const element = document.getElementById(this.sections[i].id);
if (element) {
const elementPosition = element.offsetTop - container.offsetTop;
if (elementPosition <= adjustedScrollPosition) {
if (this.activeSection !== this.sections[i].id) {
console.log(
`切换到 ${this.sections[i].label},位置: ${elementPosition},偏移: ${offset}`
);
this.activeSection = this.sections[i].id;
}
break;
}
}
}
}, 50);
},
// 子组件的更新
handleDataUpdate(dataKey, updatedData) {
if (dataKey === "projectOtherInfos" || dataKey === "wysmxInformations") {
if (Array.isArray(updatedData)) {
this[dataKey] = updatedData;
} else {
this[dataKey].push(updatedData);
}
} else {
this[dataKey] = updatedData;
}
console.log(`接收到 ${dataKey} 1234更新:`, updatedData);
},
isDefault(obj, defaultObj) {
for (const key in defaultObj) {
if (obj[key] !== defaultObj[key]) {
return false;
}
}
return true;
},
// 暂存数据
saveAll() {
// 全局加载动画
const loading = this.$loading({
lock: true,
text: "正在暂存中...",
spinner: "el-icon-loading",
background: "rgba(0, 0, 0, 0.7)",
});
const tempData = this.prepareSubmitData(); // 复用数据
tempBasicInformation(tempData)
.then((response) => {
this.$message.success("暂存成功");
})
.catch((error) => {
this.$message.error("暂存失败");
})
.finally(() => {
// 关闭动画
loading.close();
});
},
// 获取企业入驻总数
async getEnterpriseCount() {
try {
const params = { xmId: this.projectId, current: 1, size: 1 }; // 只需要总数size=1
const response = await getqyBasicInformationPage(params);
return response.data.total || 0; // 返回总数默认为0
} catch (error) {
return 0;
}
},
// 提交数据
async submitAll() {
// 创建全局加载动画
const loading = this.$loading({
lock: true,
text: "正在提交...",
spinner: "el-icon-loading",
background: "rgba(0, 0, 0, 0.7)",
});
// 校验建筑信息是否填写
if (!this.hasBuildingData) {
this.$message.error("请填写建筑信息");
loading.close();
return;
}
// 校验 wysmxInformations
if (
this.wysmxInformations.length === 0 ||
this.wysmxInformations.includes(null)
) {
this.$message.error("请填写模型管理信息");
loading.close();
return;
}
// 校验 qyrzInformation 的 rzqys
const rzqys = await this.getEnterpriseCount();
if (rzqys === 0 || rzqys === null || rzqys === undefined) {
this.$message.error("请先导入企业入驻信息");
loading.close();
return;
}
// 校验 planInformation
const planRequiredFields = [
"zydmj",
"rjl",
"zjzmj",
"jzds",
"zgjzcs",
"fhdj",
];
const planMissingFields = planRequiredFields.filter(
(field) => !this.planInformation[field]
);
if (planMissingFields.length > 0) {
this.$message.error("请填写完整的规划信息");
loading.close();
return;
}
// 校验 basicInformation
const basicRequiredFields = [
"ssgnq",
"begainTime",
"endTime",
"xzfl",
"jsms",
];
const basicMissingFields = basicRequiredFields.filter(
(field) => !this.basicInformation[field]
);
if (basicMissingFields.length > 0) {
this.$message.error("请填写完整的基本信息");
loading.close();
return;
}
// 准备数据并提交
const submitData = this.prepareSubmitData();
// console.log('准备提交的完整数据:', JSON.stringify(submitData, null, 2));
fillBasicInformation(submitData)
.then((response) => {
this.$message.success("提交成功");
this.isSubmitted = true;
this.$router.push("/manage");
})
.catch((error) => {
this.$message.error("提交失败");
console.error("提交错误:", error);
})
.finally(() => {
loading.close();
});
},
// 审核通过的提交数据
aduitAll() {
this.loading = true;
const submitData = this.prepareSubmitData();
auditBasicInformation(submitData)
.then((response) => {
console.log("提交成功:", response);
this.$message.success("审核通过");
this.isContainerVisible = false;
this.isSubmitted = true;
this.$router.push("/manage");
})
.finally(() => {
this.loading = false;
});
},
// 准备数据(供暂存和提交共用)
prepareSubmitData() {
return {
basicInformation: this.basicInformation,
planInformation: this.planInformation,
projectOtherInfos: this.projectOtherInfos,
qyrzInformation: this.qyrzInformation,
wysmxInformations: this.formatWysmxData(),
};
},
// 格式化要素模型数据
formatWysmxData() {
return this.wysmxInformations.flatMap((item) =>
item.list.map((listItem) => ({
id: listItem.id,
createTime: this.formatDate(new Date()),
updateTime: this.formatDate(new Date()),
xmId: this.projectId,
ysmc: item.ysmc,
zdinfor: listItem.zdinfor,
zdname: listItem.zdname,
createBy: "",
updateBy: "",
createId: 0,
updateId: 0,
}))
);
},
// 日期格式化方法
formatDate(date) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
const hours = String(date.getHours()).padStart(2, "0");
const minutes = String(date.getMinutes()).padStart(2, "0");
const seconds = String(date.getSeconds()).padStart(2, "0");
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
},
handleMenuClick() {
if (this.$refs.menuRef) {
this.$refs.menuRef.$el.blur();
}
},
},
};
</script>
<style scoped>
.containerbody {
height: calc(100% - 7rem);
padding: 0.3rem 0.5rem;
display: flex;
flex-direction: column;
gap: 1rem;
position: relative;
overflow: hidden;
overflow-y: auto;
}
.containerheadone {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
padding: 0 1rem 0 0.7rem;
background-color: #fff;
}
.containerhead {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
background-color: #ffffff;
}
.custom-menu {
margin: 1rem 0rem;
display: flex;
gap: 1rem;
border: none;
outline: none !important;
}
.custom-menu-item {
color: #3d424c;
width: auto;
height: 2rem;
background: #f4f7fe;
border-radius: 0.25rem 0.25rem 0.25rem 0.25rem;
display: flex;
align-items: center;
justify-content: center;
}
/* 高亮 */
.custom-menu-item.is-active {
background-color: #2b62f1;
color: #fff !important;
}
/* 悬停 */
.custom-menu-item:hover {
background-color: #2b62f1;
color: #fff !important;
}
/* 默认的下划线 */
.el-menu--horizontal .el-menu-item:not(.is-disabled):focus,
.el-menu--horizontal .el-menu-item:not(.is-disabled):hover {
background-color: #2b62f1;
border-bottom: none;
}
/* 移除菜单焦点样式 */
.custom-menu:focus,
.custom-menu:focus-within,
.custom-menu-item:focus,
.el-menu--horizontal .el-menu-item:focus {
outline: none !important;
box-shadow: none !important;
border: none !important;
}
.bottombox {
margin-bottom: 2rem;
}
.bigone {
position: relative;
height: 100%;
width: 100%;
overflow: hidden;
}
.message-notice {
position: fixed;
bottom: 40%;
right: 1%;
z-index: 1000;
font-size: 23px;
cursor: pointer;
}
.footer {
display: flex;
padding: 0 0 2rem 0;
justify-content: center;
}
</style>