组件修改

main
严飞永 1 week ago
parent 5ba5d688ad
commit b84c630c4a

@ -40,9 +40,6 @@
<el-col :span="1.5"> <el-col :span="1.5">
<el-button type="primary" icon="el-icon-download" size="medium" @click="handleImport"></el-button> <el-button type="primary" icon="el-icon-download" size="medium" @click="handleImport"></el-button>
</el-col> </el-col>
<!-- <el-col :span="1.5">
<el-button type="primary" icon="el-icon-download" size="medium" @click="handleExport"></el-button>
</el-col> -->
</el-row> </el-row>
</div> </div>
<el-table v-loading="loading" :data="postList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="postList" @selection-change="handleSelectionChange">
@ -108,7 +105,7 @@
<el-date-picker v-model="form.scsj" type="date" placeholder="选择日期" value-format="yyyy-MM-dd" <el-date-picker v-model="form.scsj" type="date" placeholder="选择日期" value-format="yyyy-MM-dd"
style="width: 100%;" /> style="width: 100%;" />
</el-form-item> </el-form-item>
<el-form-item v-if="form.lx !== '3'" label="附件" prop="fj" required> <el-form-item v-if="form.lx !== '3'" label="附件" prop="fj" required :message="文件名称不能为空">
<fileload v-model="form.fj"></fileload> <fileload v-model="form.fj"></fileload>
</el-form-item> </el-form-item>
<el-form-item v-if="form.lx === '3'" label="附件" prop="fj"> <el-form-item v-if="form.lx === '3'" label="附件" prop="fj">
@ -262,6 +259,9 @@ export default {
], ],
scsj: [ scsj: [
{ required: true, message: "上传时间不能为空", trigger: "change" } { required: true, message: "上传时间不能为空", trigger: "change" }
],
fj: [
{ required: true, message: "附件不能为空", trigger: "blur" }
] ]
}, },
// //
@ -285,7 +285,7 @@ export default {
// //
headers: { Authorization: "Bearer " + getToken() }, headers: { Authorization: "Bearer " + getToken() },
// //
url: process.env.VUE_APP_BASE_API + "", url: process.env.VUE_APP_BASE_API + "/gysl/xmzsk/import",
}, },
}; };
}, },
@ -409,9 +409,7 @@ export default {
this.$modal.msgSuccess("新增成功"); this.$modal.msgSuccess("新增成功");
this.open = false; this.open = false;
this.getList(); this.getList();
}).catch(error => { }).catch(error => { });
console.error('API Request Error:', error);
});
} }
} }
}); });
@ -463,10 +461,15 @@ export default {
if (this.form.lx !== '3') { if (this.form.lx !== '3') {
this.form.wz = undefined; this.form.wz = undefined;
this.select = 'http'; this.select = 'http';
// fj
this.rules.fj[0].required = true;
} else { } else {
this.setProtocolType(this.form.wz); this.setProtocolType(this.form.wz);
// fj
this.rules.fj[0].required = false;
} }
}, },
/**导出 */ /**导出 */
// handleExport() { // handleExport() {
// this.download( // this.download(
@ -484,7 +487,7 @@ export default {
/** 下载模板操作 */ /** 下载模板操作 */
importTemplate() { importTemplate() {
this.download( this.download(
"/gysl/ml/importTemplate", "/gysl/xmzsk/importTemplate",
{}, {},
`知识库导入模板${new Date().getTime()}.xlsx` `知识库导入模板${new Date().getTime()}.xlsx`
); );

@ -18,9 +18,9 @@
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item> <el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" <el-button type="primary" icon="el-icon-search"
@click="handleQuery">查询</el-button> @click="handleQuery">查询</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button> <el-button icon="el-icon-refresh" @click="resetQuery"></el-button>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
@ -30,7 +30,7 @@
<!-- 表格内容区 --> <!-- 表格内容区 -->
<div v-if="!previewMode" class="tablebox"> <div v-if="!previewMode" class="tablebox">
<el-table v-loading="loading" :data="postList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="postList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /> <!-- <el-table-column type="selection" width="55" align="center" /> -->
<el-table-column label="序号" align="center" prop="id" /> <el-table-column label="序号" align="center" prop="id" />
<el-table-column label="文件标题" align="center" prop="title" /> <el-table-column label="文件标题" align="center" prop="title" />
<el-table-column label="发布单位" align="center" prop="unit" /> <el-table-column label="发布单位" align="center" prop="unit" />
@ -38,7 +38,7 @@
<el-table-column label="发布时间" align="center" prop="createTime" /> <el-table-column label="发布时间" align="center" prop="createTime" />
<el-table-column label="操作" align="center"> <el-table-column label="操作" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button size="mini" type="text" style="color: gray;" <el-button type="text" style="color: gray;"
@click="handlePreview(scope.row)">预览</el-button> @click="handlePreview(scope.row)">预览</el-button>
</template> </template>
</el-table-column> </el-table-column>
@ -52,7 +52,7 @@
<div class="previewhead"> <div class="previewhead">
<h3>{{ previewData.title }}</h3> <h3>{{ previewData.title }}</h3>
<div class="headtwo"> <div class="headtwo">
<el-button size="mini" @click="previewMode = false">返回</el-button> <el-button @click="previewMode = false">返回</el-button>
</div> </div>
</div> </div>
<div class="previewcontent"> <div class="previewcontent">

@ -18,9 +18,9 @@
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item> <el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" <el-button type="primary" icon="el-icon-search"
@click="handleQuery">查询</el-button> @click="handleQuery">查询</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"></el-button> <el-button icon="el-icon-refresh" @click="resetQuery"></el-button>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
@ -30,15 +30,13 @@
<!-- 表格内容区 --> <!-- 表格内容区 -->
<div v-if="!previewMode" class="tablebox"> <div v-if="!previewMode" class="tablebox">
<el-table v-loading="loading" :data="postList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="postList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="序号" align="center" prop="id" /> <el-table-column label="序号" align="center" prop="id" />
<el-table-column label="文件标题" align="center" prop="title" /> <el-table-column label="文件标题" align="center" prop="title" />
<el-table-column label="发布单位" align="center" prop="unit" /> <el-table-column label="发布单位" align="center" prop="unit" />
<!-- <el-table-column label="发布人" align="center" prop="author" /> -->
<el-table-column label="发布时间" align="center" prop="createTime" /> <el-table-column label="发布时间" align="center" prop="createTime" />
<el-table-column label="操作" align="center"> <el-table-column label="操作" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button size="mini" type="text" style="color: gray;" <el-button type="text" style="color: gray;"
@click="handlePreview(scope.row)">预览</el-button> @click="handlePreview(scope.row)">预览</el-button>
</template> </template>
</el-table-column> </el-table-column>
@ -52,7 +50,7 @@
<div class="previewhead"> <div class="previewhead">
<h3>{{ previewData.title }}</h3> <h3>{{ previewData.title }}</h3>
<div class="headtwo"> <div class="headtwo">
<el-button size="mini" @click="previewMode = false">返回</el-button> <el-button @click="previewMode = false">返回</el-button>
</div> </div>
</div> </div>
<div class="previewcontent"> <div class="previewcontent">

@ -45,14 +45,14 @@
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="项目名称" prop="name"> <el-form-item label="项目名称" prop="name">
<el-input v-model="form.name" maxlength="50"></el-input> <el-input v-model="form.name" maxlength="50" placeholder="请输入项目名称"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="建设地点" prop="jsdd"> <el-form-item label="建设地点" prop="jsdd">
<el-row :gutter="10"> <el-row :gutter="10">
<el-col :span="20"> <el-col :span="20">
<el-input v-model="form.jsdd" maxlength="50" readonly></el-input> <el-input v-model="form.jsdd" maxlength="50" placeholder="请点击右侧落图" readonly></el-input>
</el-col> </el-col>
<el-col :span="3"> <el-col :span="3">
<span @click="showMap" style="color: #2B62F1;cursor: pointer;">落图</span> <span @click="showMap" style="color: #2B62F1;cursor: pointer;">落图</span>
@ -64,12 +64,12 @@
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="项目法人单位" prop="xmfrdwxz"> <el-form-item label="项目法人单位" prop="xmfrdwxz">
<el-input v-model="form.xmfrdwxz" maxlength="50"></el-input> <el-input v-model="form.xmfrdwxz" maxlength="50" placeholder="请输入项目法人单位"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="重点发展产业" prop="prioritize"> <el-form-item label="重点发展产业" prop="prioritize">
<el-input v-model="form.prioritize" maxlength="50"></el-input> <el-input v-model="form.prioritize" maxlength="50" placeholder="请输入重点发展产业"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
@ -95,36 +95,36 @@
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="施工单位" prop="sgdw"> <el-form-item label="施工单位" prop="sgdw">
<el-input v-model="form.sgdw" maxlength="50"></el-input> <el-input v-model="form.sgdw" maxlength="50" placeholder="请输入施工单位"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="项目标签" prop="label"> <el-form-item label="项目标签" prop="label">
<el-input v-model="form.label" maxlength="50"></el-input> <el-input v-model="form.label" maxlength="50" placeholder="请输入项目标签"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="设计单位" prop="sjdw"> <el-form-item label="设计单位" prop="sjdw">
<el-input v-model="form.sjdw" maxlength="50"></el-input> <el-input v-model="form.sjdw" maxlength="50" placeholder="请输入设计单位"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="项目负责人" prop="projectLeader"> <el-form-item label="项目负责人" prop="projectLeader">
<el-input v-model="form.projectLeader" maxlength="50"></el-input> <el-input v-model="form.projectLeader" maxlength="50" placeholder="请输入项目负责人"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="总投资额(万元)" prop="ztze"> <el-form-item label="总投资额(万元)" prop="ztze">
<el-input v-model.number="form.ztze" maxlength="50"></el-input> <el-input v-model.number="form.ztze" maxlength="50" placeholder="请输入总投资额"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="联系方式" prop="phone"> <el-form-item label="联系方式" prop="phone">
<el-input v-model="form.phone" maxlength="50"></el-input> <el-input v-model="form.phone" maxlength="50" placeholder="请输入联系方式" ></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
@ -139,7 +139,7 @@
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="施工许可证发放时间" prop="issuingTime"> <el-form-item label="施工许可证发放时间" prop="issuingTime">
<el-input v-model="form.issuingTime" maxlength="50"></el-input> <el-input v-model="form.issuingTime" maxlength="50" placeholder="请输入施工许可证发放时间"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
@ -155,7 +155,7 @@
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="竣工验收时间" prop="acceptanceTime"> <el-form-item label="竣工验收时间" prop="acceptanceTime">
<el-input v-model="form.acceptanceTime" maxlength="50"></el-input> <el-input v-model="form.acceptanceTime" maxlength="50" placeholder="请输入竣工验收时间"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
@ -170,14 +170,14 @@
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="建设进度" prop="jsjd"> <el-form-item label="建设进度" prop="jsjd">
<el-input v-model="form.jsjd" maxlength="50"></el-input> <el-input v-model="form.jsjd" maxlength="50" placeholder="请输入建设进度"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="统一社会信用代码" prop="tyshxydm"> <el-form-item label="统一社会信用代码" prop="tyshxydm">
<el-input v-model="form.tyshxydm" maxlength="50"></el-input> <el-input v-model="form.tyshxydm" maxlength="50" placeholder="请输入统一社会信用代码"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
@ -194,10 +194,10 @@
</el-col> </el-col>
</el-row> </el-row>
<el-form-item label="项目法人单位简介" prop="unitIntroduction"> <el-form-item label="项目法人单位简介" prop="unitIntroduction">
<el-input v-model="form.unitIntroduction" type="textarea" rows="4" maxlength="1000"></el-input> <el-input v-model="form.unitIntroduction" type="textarea" rows="4" maxlength="1000" placeholder="请输入项目法人单位简介"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="项目简介" prop="introduction"> <el-form-item label="项目简介" prop="introduction">
<el-input v-model="form.introduction" type="textarea" rows="4" maxlength="1000"></el-input> <el-input v-model="form.introduction" type="textarea" rows="4" maxlength="1000" placeholder="请输入项目简介"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="项目代表性照片"> <el-form-item label="项目代表性照片">
<ImageUpload v-model="form.fj" /> <ImageUpload v-model="form.fj" />

@ -13,8 +13,7 @@
style="width: 0.6rem; height: 0.6rem; margin-right: 4px;"> style="width: 0.6rem; height: 0.6rem; margin-right: 4px;">
新增 新增
</el-button> </el-button>
<el-button type="primary" size="medium" plain <el-button type="primary" size="medium" plain v-if="buildings.length !== 0"
v-if="buildings.length !== 0"
style="border: none;background-color: rgba(43,98,241,0.1);color: #2B62F1;" style="border: none;background-color: rgba(43,98,241,0.1);color: #2B62F1;"
@click="handleEdit(selectedBuilding)"> @click="handleEdit(selectedBuilding)">
<img src="../../../assets/images/detailsicon/icon-bj@2x.png" alt="编辑" <img src="../../../assets/images/detailsicon/icon-bj@2x.png" alt="编辑"
@ -44,8 +43,8 @@
:class="[getTagItemClass(building), { 'active-tag': selectedBuilding && selectedBuilding.id === building.id }]"> :class="[getTagItemClass(building), { 'active-tag': selectedBuilding && selectedBuilding.id === building.id }]">
<img src="@/assets/images/detailsicon/icon-楼栋@2x.png" alt=""> <img src="@/assets/images/detailsicon/icon-楼栋@2x.png" alt="">
<span>{{ building.name }}</span> <span>{{ building.name }}</span>
<img src="@/assets/images/detailsicon/icon-gb@2x.png" v-if="action === 'fill' || !action || action === 'okay'" <img src="@/assets/images/detailsicon/icon-gb@2x.png"
alt="" v-if="action === 'fill' || !action || action === 'okay'" alt=""
@click.stop="handleDelete(building.id)"> @click.stop="handleDelete(building.id)">
</div> </div>
</div> </div>
@ -114,7 +113,7 @@
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="12"> <el-col :span="12">
<el-form-item label="楼栋名称:" prop="name"> <el-form-item label="楼栋名称:" prop="name">
<el-input v-model="buildingForm.name"></el-input> <el-input placeholder="请输入楼栋名称" v-model="buildingForm.name"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
@ -129,55 +128,55 @@
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="12"> <el-col :span="12">
<el-form-item label="首层高度(米):" prop="scgd"> <el-form-item label="首层高度(米):" prop="scgd">
<el-input v-model="buildingForm.scgd"></el-input> <el-input v-model="buildingForm.scgd" placeholder="请输入首层高度"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="层数:" prop="floor"> <el-form-item label="层数:" prop="floor">
<el-input v-model="buildingForm.floor"></el-input> <el-input v-model="buildingForm.floor" placeholder="请输入层数"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="12"> <el-col :span="12">
<el-form-item label="4层以上层高" prop="fourYscg"> <el-form-item label="4层以上层高" prop="fourYscg">
<el-input v-model="buildingForm.fourYscg"></el-input> <el-input v-model="buildingForm.fourYscg" placeholder="请输入层4层以上层高"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="柱距:" prop="zj"> <el-form-item label="柱距:" prop="zj">
<el-input v-model="buildingForm.zj"></el-input> <el-input v-model="buildingForm.zj" placeholder="请输入柱距"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="12"> <el-col :span="12">
<el-form-item label="2至4层层高" porp="twoAndFourCg"> <el-form-item label="2至4层层高" porp="twoAndFourCg">
<el-input v-model="buildingForm.twoAndFourCg"></el-input> <el-input v-model="buildingForm.twoAndFourCg" placeholder="请输入2至4层层高"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="总建筑高度(米):" prop="totalBuildingHeight"> <el-form-item label="总建筑高度(米):" prop="totalBuildingHeight">
<el-input v-model="buildingForm.totalBuildingHeight"></el-input> <el-input v-model="buildingForm.totalBuildingHeight" placeholder="请输入总建筑高度"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="12"> <el-col :span="12">
<el-form-item label="首层地面荷载(吨/平方米):" prop="scdmhz"> <el-form-item label="首层地面荷载(吨/平方米):" prop="scdmhz">
<el-input v-model="buildingForm.scdmhz"></el-input> <el-input v-model="buildingForm.scdmhz" placeholder="请输入首层地面荷载"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="二至三层楼面荷载(吨/平方米):" prop="twoAndThreeLmhz"> <el-form-item label="二至三层楼面荷载(吨/平方米):" prop="twoAndThreeLmhz">
<el-input v-model="buildingForm.twoAndThreeLmhz"></el-input> <el-input v-model="buildingForm.twoAndThreeLmhz" placeholder="请输入二至三层楼面荷载"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="12"> <el-col :span="12">
<el-form-item label="标准层面积(千平方米):" prop="bzcmj"> <el-form-item label="标准层面积(千平方米):" prop="bzcmj">
<el-input v-model="buildingForm.bzcmj"></el-input> <el-input v-model="buildingForm.bzcmj" placeholder="请输入标准层面积"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
@ -200,7 +199,7 @@
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="四层及以上楼面荷载(吨/平方米):" prop="fourYslmhz"> <el-form-item label="四层及以上楼面荷载(吨/平方米):" prop="fourYslmhz">
<el-input v-model="buildingForm.fourYslmhz"></el-input> <el-input v-model="buildingForm.fourYslmhz" placeholder="请输入四层及以上楼面荷载"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
@ -419,18 +418,17 @@ export default {
}; };
}, },
fetchBuildings() { fetchBuildings() {
// console.log('Fetching data for xmId:', this.xmId);
getjzxxinformationByxmId({ xmId: this.xmId }) getjzxxinformationByxmId({ xmId: this.xmId })
.then(response => { .then(response => {
// console.log('API response:', response);
if (response.code === 200 && response.data) { if (response.code === 200 && response.data) {
this.buildings = Object.values(response.data); // this.buildings = Object.values(response.data);
// console.log('Buildings data after assignment:', this.buildings);
// //
if (this.buildings.length > 0) { if (this.buildings.length > 0) {
this.selectedBuilding = this.buildings[0]; this.selectedBuilding = this.buildings[0];
} }
} else {} } else { }
}) })
}, },
@ -574,17 +572,6 @@ export default {
text-transform: none; text-transform: none;
} }
.tagitem {
width: 6.25rem;
height: 2rem;
background: #FAFAFA;
border-radius: 2.13rem 2.13rem 2.13rem 2.13rem;
display: flex;
justify-content: space-around;
align-items: center;
cursor: pointer;
}
.tagitem { .tagitem {
width: 6.25rem; width: 6.25rem;
height: 2rem; height: 2rem;
@ -616,7 +603,4 @@ export default {
background-color: rgba(43, 98, 241, 0.1); background-color: rgba(43, 98, 241, 0.1);
} }
.important-building {
background-color: rgba(43, 98, 241, 0.1);
}
</style> </style>

@ -6,7 +6,7 @@
<img src="../../../assets/images/detailsicon/1.png" alt=""> <img src="../../../assets/images/detailsicon/1.png" alt="">
<span>现场实况</span> <span>现场实况</span>
</div> </div>
<div class="topright" v-if="action === 'fill' || !action"> <div class="topright" v-if="action === 'fill' || !action" style="visibility: hidden;">
<el-button type="primary" size="medium" plain <el-button type="primary" size="medium" plain
style="border: none;background-color: rgba(43,98,241,0.1);color: #2B62F1;" @click=""> style="border: none;background-color: rgba(43,98,241,0.1);color: #2B62F1;" @click="">
<img src="../../../assets/images/detailsicon/icon-xz@2x.png" alt="编辑" <img src="../../../assets/images/detailsicon/icon-xz@2x.png" alt="编辑"

@ -51,11 +51,11 @@
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center"> <el-table-column label="操作" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button v-if="scope.row.isEditing" size="mini" type="text" icon="el-icon-check" <el-button v-if="scope.row.isEditing" type="text" icon="el-icon-check"
@click="handleSave(scope.row)">保存</el-button> @click="handleSave(scope.row)">保存</el-button>
<el-button v-else size="mini" type="text" icon="el-icon-edit" <el-button v-else type="text" icon="el-icon-edit"
@click="handleEdit(scope.row)">编辑</el-button> @click="handleEdit(scope.row)">编辑</el-button>
<el-button size="mini" type="text" icon="el-icon-delete" style="color: #F25353;" <el-button type="text" icon="el-icon-delete" style="color: #F25353;"
@click="handleDelete(scope.row)">删除</el-button> @click="handleDelete(scope.row)">删除</el-button>
</template> </template>
</el-table-column> </el-table-column>
@ -72,7 +72,7 @@
</template> </template>
<script> <script>
import { getMonthInformationPage } from "@/api/ManageApi/index"; // import { getMonthInformationPage } from "@/api/ManageApi/index";
export default { export default {
props: { props: {
@ -140,26 +140,26 @@ export default {
}); });
}); });
}, },
async getMonthInformationPage() { // async getMonthInformationPage() {
try { // try {
const response = await getMonthInformationPage({ xmId: this.xmId }); // const response = await getMonthInformationPage({ xmId: this.xmId });
if (Array.isArray(response.data.records) && response.data.records.length > 0) { // if (Array.isArray(response.data.records) && response.data.records.length > 0) {
this.tableData = response.data.records; // this.tableData = response.data.records;
this.total = response.data.total || 0; // this.total = response.data.total || 0;
} else { // } else {
// // //
this.tableData = []; // this.tableData = [];
this.total = 0; // this.total = 0;
} // }
} catch (error) { // } catch (error) {
console.error("获取月度进展信息失败:", error); // console.error(":", error);
this.$message.error("获取月度进展信息失败"); // this.$message.error("");
} // }
}, // },
}, },
created() { created() {
this.getMonthInformationPage(); // this.getMonthInformationPage();
}, },
}; };
</script> </script>

@ -36,7 +36,7 @@
<el-descriptions-item v-for="(item, index) in anotherInfo" :key="index" :label="item.zdname"> <el-descriptions-item v-for="(item, index) in anotherInfo" :key="index" :label="item.zdname">
<template v-if="isEditMode"> <template v-if="isEditMode">
<el-input v-model="item.zdinfor" size="small" @change="handleFieldChange(item)" <el-input v-model="item.zdinfor" size="small" @change="handleFieldChange(item)"
style="width:8rem;"></el-input> style="width:7rem;"></el-input>
</template> </template>
<template v-else> <template v-else>
{{ item.zdinfor }} {{ item.zdinfor }}
@ -332,7 +332,7 @@ export default {
.tagdiv { .tagdiv {
width: 100%; width: 100%;
padding: 1rem; padding: 1rem 2rem 1rem 0;
} }
.block { .block {

@ -31,15 +31,27 @@
<div class="content"> <div class="content">
<div class="descriptionsdiv"> <div class="descriptionsdiv">
<el-descriptions class="margin-top" :column="4" border> <el-descriptions class="margin-top" :column="4" border>
<el-descriptions-item label="总用地面积(平方米)"> <el-descriptions-item>
<template slot="label">
<span style="color: red;">*</span>
总用地面积(平方米)
</template>
<el-input v-if="isEditing" v-model="form.zydmj" style="width: 100%;"></el-input> <el-input v-if="isEditing" v-model="form.zydmj" style="width: 100%;"></el-input>
<span v-else>{{ form.zydmj }}</span> <span v-else>{{ form.zydmj }}</span>
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="容积率"> <el-descriptions-item>
<template slot="label">
<span style="color: red;">*</span>
容积率
</template>
<el-input v-if="isEditing" v-model="form.rjl" style="width: 100%;"></el-input> <el-input v-if="isEditing" v-model="form.rjl" style="width: 100%;"></el-input>
<span v-else>{{ form.rjl }}</span> <span v-else>{{ form.rjl }}</span>
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="总建筑面积(平方米)"> <el-descriptions-item>
<template slot="label">
<span style="color: red;">*</span>
总建筑面积平方米
</template>
<el-input v-if="isEditing" v-model="form.zjzmj" style="width: 100%;"></el-input> <el-input v-if="isEditing" v-model="form.zjzmj" style="width: 100%;"></el-input>
<span v-else>{{ form.zjzmj }}</span> <span v-else>{{ form.zjzmj }}</span>
</el-descriptions-item> </el-descriptions-item>
@ -59,7 +71,11 @@
<el-input v-if="isEditing" v-model="form.ldl" style="width: 100%;"></el-input> <el-input v-if="isEditing" v-model="form.ldl" style="width: 100%;"></el-input>
<span v-else>{{ form.ldl }}</span> <span v-else>{{ form.ldl }}</span>
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="建筑栋数(栋)"> <el-descriptions-item>
<template slot="label">
<span style="color: red;">*</span>
建筑栋数
</template>
<el-input v-if="isEditing" v-model="form.jzds" style="width: 100%;"></el-input> <el-input v-if="isEditing" v-model="form.jzds" style="width: 100%;"></el-input>
<span v-else>{{ form.jzds }}</span> <span v-else>{{ form.jzds }}</span>
</el-descriptions-item> </el-descriptions-item>
@ -71,7 +87,11 @@
<el-input v-if="isEditing" v-model="form.dxjzmj" style="width: 100%;"></el-input> <el-input v-if="isEditing" v-model="form.dxjzmj" style="width: 100%;"></el-input>
<span v-else>{{ form.dxjzmj }}</span> <span v-else>{{ form.dxjzmj }}</span>
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="最高建筑层数(层)"> <el-descriptions-item>
<template slot="label">
<span style="color: red;">*</span>
最高建筑层数
</template>
<el-input v-if="isEditing" v-model="form.zgjzcs" style="width: 100%;"></el-input> <el-input v-if="isEditing" v-model="form.zgjzcs" style="width: 100%;"></el-input>
<span v-else>{{ form.zgjzcs }}</span> <span v-else>{{ form.zgjzcs }}</span>
</el-descriptions-item> </el-descriptions-item>
@ -87,7 +107,11 @@
<el-input v-if="isEditing" v-model="form.fjdctcw" style="width: 100%;"></el-input> <el-input v-if="isEditing" v-model="form.fjdctcw" style="width: 100%;"></el-input>
<span v-else>{{ form.fjdctcw }}</span> <span v-else>{{ form.fjdctcw }}</span>
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="防火等级"> <el-descriptions-item>
<template slot="label">
<span style="color: red;">*</span>
防火等级
</template>
<el-input v-if="isEditing" v-model="form.fhdj" style="width: 100%;"></el-input> <el-input v-if="isEditing" v-model="form.fhdj" style="width: 100%;"></el-input>
<span v-else>{{ form.fhdj }}</span> <span v-else>{{ form.fhdj }}</span>
</el-descriptions-item> </el-descriptions-item>
@ -176,7 +200,7 @@ export default {
updateTime: null, updateTime: null,
}, },
rules: { rules: {
} }
}; };
}, },
@ -192,7 +216,6 @@ export default {
methods: { methods: {
checkPermi, checkPermi,
checkRole, checkRole,
//
/** 导出 */ /** 导出 */
handleExport() { handleExport() {
this.download( this.download(

@ -61,8 +61,8 @@ export default {
map: null, map: null,
keyword: "", // keyword: "", //
searchList: [], // searchList: [], //
searchBox: false, // searchBox: false,
searchDebounce: null, // searchDebounce: null,
}; };
}, },
methods: { methods: {
@ -205,8 +205,8 @@ export default {
.main-content { .main-content {
display: flex; display: flex;
width: 82rem; width: 74rem;
padding: 0 1rem 1rem 1rem; padding: 0 1rem 1rem 0rem;
} }
.map-container { .map-container {

@ -124,7 +124,7 @@
data() { data() {
return { return {
dialogVisible: false, dialogVisible: false,
dialogTitle: "新增智能提醒规则", dialogTitle: "新增智能提醒",
ruleForm: { ruleForm: {
rulesName: "", rulesName: "",
alertRecipients: "2", alertRecipients: "2",

@ -4,13 +4,6 @@
<div class="top"> <div class="top">
<div class="title">整体项目情况</div> <div class="title">整体项目情况</div>
<div class="importdiv"> <div class="importdiv">
<!-- <el-date-picker v-model="selectedYear" type="year" placeholder="选择年份" format="yyyy"
value-format="yyyy" @change="handleYearChange">
</el-date-picker> -->
<!-- <el-button icon="el-icon-upload2" style="background-color: #2B62F1; color: #FFFFFF;"
@click="handleExport">
报告导出
</el-button> -->
</div> </div>
</div> </div>
<div class="mainarea"> <div class="mainarea">

@ -1,10 +1,11 @@
<template> <template>
<!-- 产业导向目录分析 -->
<div> <div>
<div class="itemsall"> <div class="itemsall">
<span>{{ totalCount }}</span> <span>{{ totalCount }}</span>
<span>项目总数</span> <span>项目总数</span>
</div> </div>
<div ref="chart" style="width: 30rem; height: 13rem;"></div> <div ref="chart" style="width: 30rem; height: 9rem;"></div>
</div> </div>
</template> </template>
@ -59,14 +60,14 @@ export default {
orient: 'vertical', // orient: 'vertical', //
right: '10%', // right: '10%', //
top: 'center', // top: 'center', //
itemGap: 50, // itemGap: 30, //
formatter: function (name) { formatter: function (name) {
// //
const item = this.chartData.find(item => item.name === name); const item = this.chartData.find(item => item.name === name);
return `${name} ${item.value}`; return `${name} ${item.value}`;
}.bind(this), }.bind(this),
textStyle: { textStyle: {
fontSize: 16, // fontSize: 14, //
fontfamily: 'alibold' fontfamily: 'alibold'
} }
}, },
@ -78,7 +79,7 @@ export default {
center: ['30%', '50%'], center: ['30%', '50%'],
data: this.chartData, data: this.chartData,
label: { label: {
show: false // show: false
}, },
emphasis: { emphasis: {
itemStyle: { itemStyle: {
@ -104,14 +105,14 @@ export default {
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
top: 3.8rem; top: 3.2rem;
left: 7rem; left: 7.5rem;
} }
.itemsall span:nth-child(1) { .itemsall span:nth-child(1) {
font-family: DINbold; font-family: DINbold;
font-weight: 500; font-weight: 500;
font-size: 2rem; font-size: 1.2rem;
color: #292C33; color: #292C33;
text-align: left; text-align: left;
font-style: normal; font-style: normal;
@ -121,7 +122,7 @@ export default {
.itemsall span:nth-child(2) { .itemsall span:nth-child(2) {
font-family: alibold; font-family: alibold;
font-weight: 400; font-weight: 400;
font-size: 1rem; font-size: .7rem;
color: #9E9E9E; color: #9E9E9E;
text-align: left; text-align: left;
font-style: normal; font-style: normal;

@ -1,11 +1,12 @@
<template> <template>
<div> <!-- 产业数据分析 -->
<div class="itemsall"> <div>
<span>{{ totalCount }}</span> <div class="itemsall">
<span>项目总数</span> <span>{{ totalCount }}</span>
</div> <span>项目总数</span>
<div ref="chart" style="width: 30rem; height: 13rem;"></div> </div>
</div> <div ref="chart" style="width: 30rem; height: 9rem;"></div>
</div>
</template> </template>
<script> <script>
@ -13,101 +14,105 @@ import * as echarts from 'echarts';
import { allchanye } from '@/api/ManageApi/index'; import { allchanye } from '@/api/ManageApi/index';
export default { export default {
name: 'RingChart', name: 'RingChart',
data() { data() {
return { return {
chartData: [ chartData: [
{ value: 54, name: '细分产业分析', itemStyle: { color: '#36C3FB' } }, { value: 54, name: '细分产业分析', itemStyle: { color: '#36C3FB' }},
{ value: 65, name: '目录分析', itemStyle: { color: '#F6B600' } }, { value: 65, name: '目录分析', itemStyle: { color: '#F6B600' } },
], ],
totalCount: 0 totalCount: 0
}; };
},
mounted() {
this.getData();
},
methods: {
async getData() {
const response = await allchanye();
if (response && response.code === 200 && response.data) {
this.chartData = this.processData(response.data);
this.calculateTotal();
this.renderChart();
} else { }
},
processData(data) {
const names = ['细分产业分析', '目录分析'];
const counts = data.map(item => item.count);
return names.map((name, index) => ({
value: counts[index] || 0,
name: name,
itemStyle: { color: ['#36C3FB', '#F6B600'][index] },
}));
}, },
mounted() { calculateTotal() {
this.getData(); // value
this.totalCount = this.chartData.reduce((sum, item) => sum + item.value, 0);
}, },
methods: { renderChart() {
async getData() { const chartDom = this.$refs.chart;
const response = await allchanye(); const myChart = echarts.init(chartDom);
if (response && response.code === 200 && response.data) { const option = {
this.chartData = this.processData(response.data); tooltip: {
this.calculateTotal(); // trigger: 'item'
this.renderChart(); },
} else {} legend: {
}, orient: 'vertical', //
processData(data) { right: '10%', //
const names = ['细分产业分析', '目录分析']; top: 'center', //
const counts = data.map(item => item.count); itemGap: 30, //
return names.map((name, index) => ({ formatter: function (name) {
value: counts[index] || 0, //
name: name, const item = this.chartData.find(item => item.name === name);
itemStyle: { color: ['#36C3FB', '#F6B600'][index] }, return `${name} ${item.value}`;
})); }.bind(this),
}, textStyle: {
calculateTotal() { fontSize: 14, //
// value fontfamily: 'alibold'
this.totalCount = this.chartData.reduce((sum, item) => sum + item.value, 0); }
}, },
renderChart() { series: [
const chartDom = this.$refs.chart; {
const myChart = echarts.init(chartDom); name: '项目分布',
const option = { type: 'pie',
tooltip: { radius: ['40%', '60%'],
trigger: 'item' center: ['30%', '50%'],
}, data: this.chartData,
legend: { label: {
orient: 'vertical', // show: false //
right: '10%', // },
top: 'center', // emphasis: {
itemGap: 50, // itemStyle: {
formatter: function (name) { shadowBlur: 10,
// shadowOffsetX: 0,
const item = this.chartData.find(item => item.name === name); shadowColor: 'rgba(0, 0, 0, 0.5)'
return `${name} ${item.value}`;
}.bind(this)
},
series: [
{
name: '项目分布',
type: 'pie',
radius: ['40%', '60%'],
center: ['30%', '50%'],
data: this.chartData,
label: {
show: false //
},
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
} }
} }
] }
}; ]
};
myChart.setOption(option);
} myChart.setOption(option);
} }
}
}; };
</script> </script>
<style scoped> <style scoped>
.itemsall { .itemsall {
position: absolute; position: absolute;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
top: 3.8rem; top: 3.2rem;
left: 7rem; left: 7.5rem;
} }
.itemsall span:nth-child(1) { .itemsall span:nth-child(1) {
font-family: DINbold; font-family: DINbold;
font-weight: 500; font-weight: 500;
font-size: 2rem; font-size: 1.2rem;
color: #292C33; color: #292C33;
text-align: left; text-align: left;
font-style: normal; font-style: normal;
@ -117,7 +122,7 @@ export default {
.itemsall span:nth-child(2) { .itemsall span:nth-child(2) {
font-family: alibold; font-family: alibold;
font-weight: 400; font-weight: 400;
font-size: 1rem; font-size: .7rem;
color: #9E9E9E; color: #9E9E9E;
text-align: left; text-align: left;
font-style: normal; font-style: normal;

@ -1,12 +1,14 @@
<template> <template>
<!-- 产业导向细分产业分析 -->
<div class="progress-container"> <div class="progress-container">
<div class="progress-item" v-for="(item, index) in progressData" :key="index"> <div class="progress-item" v-for="(item, index) in progressData" :key="index">
<span class="progress-label">{{ item.label }}</span> <span class="progress-label">{{ item.label }}</span>
<div class="progress-bar-wrapper"> <div class="progress-bar-wrapper">
<div class="progress-bar" :style="{ width: item.percentage + '%', background: item.color }"> <div class="progress-bar" :style="getProgressBarStyle(item)">
</div> </div>
</div> </div>
<span class="progress-value">{{item.value}}</span> <span class="progress-value">{{item.value}}
</span>
</div> </div>
</div> </div>
</template> </template>
@ -18,7 +20,9 @@ export default {
name: 'ProgressBarWithLabel', name: 'ProgressBarWithLabel',
data() { data() {
return { return {
progressData: [], progressData: [
],
maxValue: 0 maxValue: 0
}; };
}, },
@ -29,13 +33,10 @@ export default {
async fetchData() { async fetchData() {
try { try {
const response = await allchanyexfcyfx(); const response = await allchanyexfcyfx();
// response.data
const data = response.data; const data = response.data;
//
this.maxValue = Math.max(...data.map(item => item.count)); this.maxValue = Math.max(...data.map(item => item.count));
// progressData
this.progressData = data.map((item, index) => ({ this.progressData = data.map((item, index) => ({
label: item.ssgnq, label: item.ssgnq,
value: item.count, value: item.count,
@ -45,6 +46,19 @@ export default {
} catch (error) { } catch (error) {
console.error('Error fetching data:', error); console.error('Error fetching data:', error);
} }
},
getProgressBarStyle(item) {
if (item.value === 0) {
return {
width: '100%',
background: '#e0e0e0'
};
} else {
return {
width: item.percentage + '%',
background: 'linear-gradient(90deg, #ffffff, #5B76F9)'
};
}
} }
} }
}; };
@ -53,9 +67,10 @@ export default {
<style scoped> <style scoped>
.progress-container { .progress-container {
width: 100%; width: 100%;
max-width: 34rem; height: 9rem;
margin: 0 auto; padding: 0 3rem 0 0;
font-family: Arial, sans-serif; overflow: auto;
font-family: aliregular;
} }
.progress-item { .progress-item {
@ -91,7 +106,6 @@ export default {
.progress-value { .progress-value {
width: 1.5rem; width: 1.5rem;
/* background-color: red; */
text-align: right; text-align: right;
margin-left: .3rem; margin-left: .3rem;
color: #333; color: #333;

@ -1,13 +0,0 @@
<template>
<div>
<div>123</div>
</div>
</template>
<script>
</script>
<style scoped>
</style>

@ -13,9 +13,9 @@
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button size="mini" type="text" @click="getInfo(scope.row, 'fill')" <el-button type="text" @click="getInfo(scope.row, 'fill')"
v-if="statusMap[scope.row.status] === '待填报'">填报</el-button> v-if="statusMap[scope.row.status] === '待填报'">填报</el-button>
<el-button size="mini" type="text" @click="getInfo(scope.row, 'detail')" <el-button type="text" @click="getInfo(scope.row, 'detail')"
v-if="statusMap[scope.row.status] !== '待填报'" v-if="statusMap[scope.row.status] !== '待填报'"
>详情</el-button> >详情</el-button>
</template> </template>

@ -1,16 +1,24 @@
<template> <template>
<!-- 功能区 --> <!-- 功能区 -->
<div ref="chart" style="width: 30rem; height: 10rem;"></div> <div style="width: 100%;height: 100%;">
<div class="itemsall">
<span>{{ functionnumber }}</span>
<span>项目总数</span>
</div>
<div ref="chart" style="width: 30rem; height: 100%;">
</div>
</div>
</template> </template>
<script> <script>
import * as echarts from 'echarts'; import * as echarts from 'echarts';
import { fungong } from '@/api/ManageApi/index'; import { fungong } from '@/api/ManageApi/index';
export default { export default {
name: 'FunctionChart', name: 'FunctionChart',
data() { data() {
return { return {
functionnumber: 0,
chartData: [ chartData: [
{ value: 54, name: '高端制造与国际贸易区', itemStyle: { color: '#36C3FB' } }, { value: 54, name: '高端制造与国际贸易区', itemStyle: { color: '#36C3FB' } },
{ value: 65, name: '独墅湖科教创新区', itemStyle: { color: '#5B76F9' } }, { value: 65, name: '独墅湖科教创新区', itemStyle: { color: '#5B76F9' } },
@ -28,12 +36,14 @@ export default {
try { try {
const response = await fungong(); const response = await fungong();
if (response && response.code === 200 && response.data) { if (response && response.code === 200 && response.data) {
const totalnumber = response.data.reduce((sum, item) => sum + item.count, 0);
this.functionnumber = totalnumber;
this.chartData = this.processData(response.data); this.chartData = this.processData(response.data);
this.renderChart(); this.renderChart();
} else { } } else { }
} catch (error) { } } catch (error) { }
}, },
processData(data) { processData(data) {
const names = ['高端制造与国际贸易区', '独墅湖科教创新区', '阳澄湖半岛旅游度假区', '金鸡湖商务区', '苏相合作区']; const names = ['高端制造与国际贸易区', '独墅湖科教创新区', '阳澄湖半岛旅游度假区', '金鸡湖商务区', '苏相合作区'];
const counts = data.map(item => item.count); const counts = data.map(item => item.count);
@ -43,7 +53,7 @@ export default {
value: counts[index] || 0, value: counts[index] || 0,
name: name, name: name,
itemStyle: { color: ['#36C3FB', '#5B76F9', '#F08445', '#F6B600', '#50DFB3'][index] }, itemStyle: { color: ['#36C3FB', '#5B76F9', '#F08445', '#F6B600', '#50DFB3'][index] },
percent: ((counts[index] || 0) / total * 100).toFixed(2) percent: ((counts[index] || 0) / total * 100).toFixed(2)
})); }));
}, },
renderChart() { renderChart() {
@ -61,7 +71,7 @@ export default {
orient: 'vertical', // orient: 'vertical', //
right: '0%', // right: '0%', //
top: 'center', // top: 'center', //
itemGap: 18, // itemGap: 10, //
formatter: function (name) { formatter: function (name) {
// //
const item = this.chartData.find(item => item.name === name); const item = this.chartData.find(item => item.name === name);
@ -96,5 +106,33 @@ export default {
</script> </script>
<style scoped> <style scoped>
.itemsall {
position: absolute;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
top: 35%;
left: 23%;
}
.itemsall span:nth-child(1) {
font-family: DINbold;
font-weight: 500;
font-size: 1.25rem;
color: #292C33;
text-align: left;
font-style: normal;
text-transform: none;
}
.itemsall span:nth-child(2) {
font-family: alibold;
font-weight: 400;
font-size: 0.68rem;
color: #9E9E9E;
text-align: left;
font-style: normal;
text-transform: none;
}
</style> </style>

@ -1,6 +1,12 @@
<template> <template>
<!-- 投资主体 --> <!-- 投资主体 -->
<div ref="chart" style="width: 30rem; height: 10rem;"></div> <div style="width: 100%;height: 100%;">
<div class="itemsall">
<span>{{ functionnumber }}</span>
<span>项目总数</span>
</div>
<div ref="chart" style="width: 30rem; height: 100%;"></div>
</div>
</template> </template>
<script> <script>
@ -12,6 +18,7 @@ export default {
name: 'RingChart', name: 'RingChart',
data() { data() {
return { return {
functionnumber:0,
chartData: [ chartData: [
{ value: 54, name: '国企', itemStyle: { color: '#36C3FB' } }, { value: 54, name: '国企', itemStyle: { color: '#36C3FB' } },
{ value: 65, name: '民企', itemStyle: { color: '#5B76F9' } }, { value: 65, name: '民企', itemStyle: { color: '#5B76F9' } },
@ -27,12 +34,15 @@ export default {
async getData() { async getData() {
const response = await investall(); const response = await investall();
if (response && response.code === 200 && response.data) { if (response && response.code === 200 && response.data) {
const totalCount = response.data.reduce((sum, item) => sum + item.count, 0);
this.functionnumber = totalCount;
this.chartData = this.processData(response.data); this.chartData = this.processData(response.data);
this.renderChart(); this.renderChart();
} else {} } else {}
}, },
processData(data) { processData(data) {
const names = ['国企', '民企', '外企','其他']; const names = ['国企', '民企', '外企', '其他'];
const counts = data.map(item => item.count); const counts = data.map(item => item.count);
return names.map((name, index) => ({ return names.map((name, index) => ({
value: counts[index] || 0, value: counts[index] || 0,
@ -49,9 +59,9 @@ export default {
}, },
legend: { legend: {
orient: 'vertical', // orient: 'vertical', //
right: '20%', // right: '18.5%', //
top: 'center', // top: 'center', //
itemGap: 30, // itemGap: 18, //
formatter: function (name) { formatter: function (name) {
// //
const item = this.chartData.find(item => item.name === name); const item = this.chartData.find(item => item.name === name);
@ -66,7 +76,7 @@ export default {
center: ['30%', '50%'], center: ['30%', '50%'],
data: this.chartData, data: this.chartData,
label: { label: {
show: false // show: false
}, },
emphasis: { emphasis: {
itemStyle: { itemStyle: {
@ -85,4 +95,34 @@ export default {
}; };
</script> </script>
<style scoped></style> <style scoped>
.itemsall {
position: absolute;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
top: 35%;
left: 23%;
}
.itemsall span:nth-child(1) {
font-family: DINbold;
font-weight: 500;
font-size: 1.25rem;
color: #292C33;
text-align: left;
font-style: normal;
text-transform: none;
}
.itemsall span:nth-child(2) {
font-family: alibold;
font-weight: 400;
font-size: 0.68rem;
color: #9E9E9E;
text-align: left;
font-style: normal;
text-transform: none;
}
</style>

@ -33,6 +33,7 @@
<!-- 右侧地图区域 --> <!-- 右侧地图区域 -->
<div class="map-container"> <div class="map-container">
<div id="mars2dContainerSSS" class="mars2d-container"></div> <div id="mars2dContainerSSS" class="mars2d-container"></div>
</div> </div>
</div> </div>
</div> </div>
@ -67,7 +68,11 @@ import ProjectList from '@/views/components/analysis/projectList.vue'
import { getBasicInformationPage } from "@/api/ManageApi/index"; import { getBasicInformationPage } from "@/api/ManageApi/index";
import { debounce } from 'lodash'; import { debounce } from 'lodash';
// import suzhouData from '@/assets/json/suzhou.json'
//
//
const clickOutside = { const clickOutside = {
bind(el, binding, vnode) { bind(el, binding, vnode) {
el.clickOutsideEvent = function (event) { el.clickOutsideEvent = function (event) {
@ -92,6 +97,8 @@ export default {
data() { data() {
const basePathUrl = window.basePathUrl || ""; const basePathUrl = window.basePathUrl || "";
return { return {
markerIcon: require('@/assets/images/detailsicon/icon-定位@2x.png'),
projectMarker: null,
isCollapsed: false, isCollapsed: false,
searchBox: '', searchBox: '',
searchList: [], searchList: [],
@ -138,11 +145,11 @@ export default {
show: true show: true
} }
], ],
center: { lat: 31.3456, lng: 120.5957 }, center: { lat: 31.3356, lng: 120.7157 },
zoom: 11, zoom: 11,
minZoom: 10, minZoom: 10,
maxZoom: 20, maxZoom: 20,
zoomControl: true, // zoomControl: true,
chinaCRS: 'GCJ02' chinaCRS: 'GCJ02'
}, },
map: null map: null
@ -166,27 +173,23 @@ export default {
this.map.on('load', this.onMapLoad); this.map.on('load', this.onMapLoad);
}, },
//
onMapLoad() { onMapLoad() {
// console.log('');
this.addSuzhouIndustrialParkLayer(); this.addSuzhouIndustrialParkLayer();
}, },
// //
async addSuzhouIndustrialParkLayer() { async addSuzhouIndustrialParkLayer() {
try { try {
const response = await fetch('/config/suzhou.json'); const geoJsonData = suzhouData; // 使
const geoJsonData = await response.json();
const graphicLayer = new mars2d.layer.GraphicLayer({ const graphicLayer = new mars2d.layer.GraphicLayer({
name: "苏州园区高亮区域", name: "苏州园区高亮区域",
zIndex: 10 zIndex: 10
}); });
this.map.addLayer(graphicLayer); this.map.addLayer(graphicLayer);
// 3. GeoJSON
const polygon = mars2d.Util.geoJsonToGraphics(geoJsonData, { const polygon = mars2d.Util.geoJsonToGraphics(geoJsonData, {
style: { style: {
fill: true, fill: true,
fillColor: "#2B62F1", fillColor: "#2B62F1",
fillOpacity: 0.3, fillOpacity: 0.3,
stroke: true, stroke: true,
color: "#2B62F1", color: "#2B62F1",
opacity: 0.8, opacity: 0.8,
@ -195,14 +198,9 @@ export default {
tooltip: "苏州工业园区" tooltip: "苏州工业园区"
}); });
graphicLayer.addGraphic(polygon); graphicLayer.addGraphic(polygon);
} catch (error) {
} catch (error) {} console.error('加载苏州园区数据失败:', error);
}, }
handleClear() {
this.showLocationIcon = false;
this.searchList = [];
this.hasSearched = false;
}, },
toggleCollapse() { toggleCollapse() {
this.isCollapsed = !this.isCollapsed; this.isCollapsed = !this.isCollapsed;
@ -212,6 +210,7 @@ export default {
this.searchList = []; this.searchList = [];
this.hasSearched = false; this.hasSearched = false;
this.showLocationIcon = false; this.showLocationIcon = false;
this.showLocationIcon = false;
return; return;
} }
this.debouncedSearch(); this.debouncedSearch();
@ -234,18 +233,23 @@ export default {
this.hasSearched = true; this.hasSearched = true;
if (response && response.code === 200 && response.data) { if (response && response.code === 200 && response.data) {
this.searchList = response.data.records; this.searchList = response.data.records;
if (this.searchList.length === 0) {
this.$message.warning('查无此项目');
}
} else { } else {
this.searchList = []; this.searchList = [];
this.$message.warning('查无此项目');
} }
}) })
.catch(error => { .catch(error => {
console.error('搜索失败:', error); console.error('搜索失败:', error);
this.hasSearched = true; this.hasSearched = true;
this.searchList = []; this.searchList = [];
this.$message.error('搜索失败,请重试');
}); });
}, },
centerMap(item) { centerMap(item) {
if (!item.jsdd) { if (!item.longitude || !item.latitude) {
this.$message.warning('该项目未落图!'); this.$message.warning('该项目未落图!');
return; return;
} }
@ -267,56 +271,61 @@ export default {
this.map.flyTo([lat, lng], 17); this.map.flyTo([lat, lng], 17);
} }
this.showLocationIcon = true; //
this.setRandomIconPosition(); this.map.flyTo([item.latitude, item.longitude], 17);
this.showDialog();
//
this.addProjectMarker(item);
}, },
showDialog() { handleClear() {
if (this.selectedProject.name) { this.showLocationIcon = false;
this.dialogVisible = true; this.searchList = [];
} else { this.hasSearched = false;
this.$message.warning('请选择一个项目'); this.searchBox = '';
this.dialogVisible = false;
//
if (this.projectMarker) {
this.map.removeLayer(this.projectMarker);
this.projectMarker = null;
}
this.map.setView(this.mapOptions.center, this.mapOptions.zoom);
},
addProjectMarker(item) {
if (this.projectMarker) {
this.map.removeLayer(this.projectMarker);
} }
this.projectMarker = new mars2d.graphic.Marker({
latlng: [item.latitude, item.longitude],
style: {
image: this.markerIcon,
width: 32,
height: 44,
anchor: [16, 44]
},
interactive: true,
cursor: 'pointer'
});
//
this.projectMarker.on(mars2d.EventType.click, (event) => {
this.selectedProject = { ...item };
this.dialogVisible = true;
});
this.map.addLayer(this.projectMarker);
},
showDialog() {
this.dialogVisible = true;
}, },
closeDialog() { closeDialog() {
this.dialogVisible = false; this.dialogVisible = false;
}, },
setRandomIconPosition() {
//
const maxTop = 105;
const maxLeft = 110;
const randomTop = Math.floor(Math.random() * maxTop);
const randomLeft = Math.floor(Math.random() * maxLeft);
this.iconPosition = {
position: 'absolute',
top: `${randomTop}px`,
left: `${randomLeft}px`,
cursor: 'pointer'
};
}
} }
} }
</script> </script>
<style scoped> <style scoped>
.container {
position: relative;
}
.containertwo {
position: relative;
}
.mapareaone {
height: 24.5rem;
grid-column: span 2;
width: 100%;
position: relative;
}
/* 控制按钮样式 */
.collapse-control { .collapse-control {
position: absolute; position: absolute;
left: -1.5rem; left: -1.5rem;
@ -328,7 +337,7 @@ export default {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
z-index: 10000; z-index: 1001;
transition: all 0.3s ease; transition: all 0.3s ease;
} }
@ -338,7 +347,7 @@ export default {
} }
.leftdiv { .leftdiv {
width: 36%; width: 38%;
height: 100%; height: 100%;
position: absolute; position: absolute;
left: 0rem; left: 0rem;
@ -346,7 +355,9 @@ export default {
background: #FFFFFF; background: #FFFFFF;
border-radius: 0.5rem; border-radius: 0.5rem;
transition: all 0.3s ease; transition: all 0.3s ease;
z-index: 9999; z-index: 1000;
overflow: hidden;
overflow-y: auto;
} }
.mainarea { .mainarea {
@ -354,20 +365,6 @@ export default {
overflow: auto; overflow: auto;
} }
.blueicon {
width: 20rem;
height: 20rem;
position: absolute;
background-image: url(../../../assets/images/行政区划@2x.png);
background-repeat: no-repeat;
background-size: 100% 100%;
top: 4.5rem;
right: 7.4rem;
display: flex;
justify-content: center;
align-items: center;
}
.icondiv { .icondiv {
width: 8rem; width: 8rem;
height: 8rem; height: 8rem;
@ -389,7 +386,7 @@ export default {
position: absolute; position: absolute;
right: 1rem; right: 1rem;
top: 1rem; top: 1rem;
z-index: 9999; z-index: 900;
} }
.search-results { .search-results {
@ -401,7 +398,7 @@ export default {
border: 1px solid #E5E5E5; border: 1px solid #E5E5E5;
border-radius: 0.5rem; border-radius: 0.5rem;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
z-index: 9999; z-index: 900;
max-height: 15rem; max-height: 15rem;
overflow-y: auto; overflow-y: auto;
} }
@ -425,12 +422,12 @@ export default {
color: #606266; color: #606266;
} }
/* 悬浮div样式 */ /* 悬浮div */
.app-container { .app-container {
position: absolute; position: absolute;
top: 19%; top: 20%;
left: 39%; left: 53%;
height: 17rem; height: 15rem;
width: 18rem; width: 18rem;
background-color: #fff; background-color: #fff;
border-radius: 4px; border-radius: 4px;
@ -488,7 +485,24 @@ export default {
font-family: aliregular; font-family: aliregular;
} }
/* 地图容器样式 */ /* 所有容器 */
.container {
position: relative;
height: 100%;
}
.mapareaone {
height: 100%;
grid-column: span 2;
width: 100%;
position: relative;
}
.containertwo {
height: 100%;
position: relative;
}
.map-container { .map-container {
width: 100%; width: 100%;
height: 100%; height: 100%;

@ -1,8 +1,8 @@
<template> <template>
<div class="container"> <div class="container">
<el-table :data="tableData" style="width: 100%" :show-header="false" @row-click="handleRowClick"> <el-table :data="tableData" style="width: 100%" :show-header="false" @row-click="handleRowClick">
<el-table-column width="80"> <el-table-column>
<template slot-scope="scope"> <template slot-scope="scope" width="80">
<img :src="getIcon(scope.$index)" alt="icon" style="width: 2.19rem; height: 1.25rem;"> <img :src="getIcon(scope.$index)" alt="icon" style="width: 2.19rem; height: 1.25rem;">
</template> </template>
</el-table-column> </el-table-column>
@ -13,21 +13,18 @@
</span> </span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="date" width="100"> <el-table-column prop="alertTime">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.date }} {{ formatDate(scope.row.alertTime) }}
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<!-- <div v-if="tableData.length === 0" class="no-data">
暂无数据
</div> -->
<!-- 详情弹窗 --> <!-- 详情弹窗 -->
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="40%"> <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="40%">
<div> <div>
<p><strong>时间:</strong> {{ selectedMessage.date || '暂无' }}</p>
<p><strong>内容:</strong> {{ selectedMessage.name }}</p> <p><strong>内容:</strong> {{ selectedMessage.name }}</p>
<p><strong>时间:</strong> {{ selectedMessage.alertTime}}</p>
</div> </div>
<span slot="footer" class="dialog-footer"> <span slot="footer" class="dialog-footer">
<el-button type="primary" @click="handleConfirm"></el-button> <el-button type="primary" @click="handleConfirm"></el-button>
@ -50,7 +47,7 @@ export default {
selectedMessage: { selectedMessage: {
id: '', id: '',
name: '', name: '',
date: '' alertTime: ''
}, },
dialogTitle: '消息详情' dialogTitle: '消息详情'
}; };
@ -70,7 +67,7 @@ export default {
return data.map(item => ({ return data.map(item => ({
id: item.id, id: item.id,
name: item.content, name: item.content,
date: this.formatDate(item.createTime), alertTime: item.alertTime,
isRead: item.isRead // isRead isRead: item.isRead // isRead
})); }));
}, },
@ -122,10 +119,10 @@ export default {
<style scoped> <style scoped>
.container { .container {
width: 98%; width: 98%;
height: 14.5rem; height: 11.5rem;
/* background-color: lightblue; */ /* background-color: lightblue; */
} }
.no-data{ .no-data {
color: gray; color: gray;
} }
</style> </style>

@ -1,8 +1,8 @@
<template> <template>
<div class="container"> <div class="container">
<el-table :data="tableData" style="width: 100%" :show-header="false" @row-click="handleRowClick"> <el-table :data="tableData" style="width: 100%" :show-header="false" @row-click="handleRowClick">
<el-table-column width="80"> <el-table-column>
<template slot-scope="scope"> <template slot-scope="scope" width="80">
<img :src="getIcon(scope.$index)" alt="icon" style="width: 2.19rem; height: 1.25rem;"> <img :src="getIcon(scope.$index)" alt="icon" style="width: 2.19rem; height: 1.25rem;">
</template> </template>
</el-table-column> </el-table-column>
@ -13,21 +13,18 @@
</span> </span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="date" width="100"> <el-table-column prop="alertTime">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.date }} {{ formatDate(scope.row.alertTime) }}
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<!-- <div v-if="tableData.length === 0" class="no-data">
暂无数据
</div> -->
<!-- 详情弹窗 --> <!-- 详情弹窗 -->
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="40%"> <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="40%">
<div> <div>
<p><strong>时间:</strong> {{ selectedMessage.date || '暂无' }}</p>
<p><strong>内容:</strong> {{ selectedMessage.name }}</p> <p><strong>内容:</strong> {{ selectedMessage.name }}</p>
<p><strong>时间:</strong> {{ selectedMessage.alertTime}}</p>
</div> </div>
<span slot="footer" class="dialog-footer"> <span slot="footer" class="dialog-footer">
<el-button type="primary" @click="handleConfirm"></el-button> <el-button type="primary" @click="handleConfirm"></el-button>
@ -37,7 +34,6 @@
</div> </div>
</template> </template>
<script> <script>
import { getAllMessagestwo } from '@/api/ManageApi/index'; import { getAllMessagestwo } from '@/api/ManageApi/index';
import { markSmartReminderAsRead } from '@/api/ManageApi/index'; import { markSmartReminderAsRead } from '@/api/ManageApi/index';
@ -51,7 +47,7 @@ export default {
selectedMessage: { selectedMessage: {
id: '', id: '',
name: '', name: '',
date: '' alertTime: ''
}, },
dialogTitle: '消息详情' dialogTitle: '消息详情'
}; };
@ -71,7 +67,7 @@ export default {
return data.map(item => ({ return data.map(item => ({
id: item.id, id: item.id,
name: item.content, name: item.content,
date: this.formatDate(item.createTime), alertTime: item.alertTime,
isRead: item.isRead // isRead isRead: item.isRead // isRead
})); }));
}, },
@ -122,10 +118,11 @@ export default {
<style scoped> <style scoped>
.container { .container {
width: 30rem; width: 98%;
height: 14.5rem; height: 11.5rem;
/* background-color: lightblue; */
} }
.no-data{ .no-data {
color: gray; color: gray;
} }
</style> </style>

File diff suppressed because it is too large Load Diff

@ -50,9 +50,9 @@
<!-- 表格内容区 --> <!-- 表格内容区 -->
<div class="tablebox"> <div class="tablebox">
<!-- 标签行 --> <!-- 标签行 -->
<div class="tablehead"> <!-- <div class="tablehead">
<div class="headtitle"><span>项目清单</span></div> <div class="headtitle"><span>项目清单</span></div>
</div> </div> -->
<!-- 导入弹窗 --> <!-- 导入弹窗 -->
<el-dialog title="导入" :visible.sync="upload.open" width="400px" append-to-body> <el-dialog title="导入" :visible.sync="upload.open" width="400px" append-to-body>
<el-upload ref="upload" :limit="1" accept=".xlsx, .xls" :headers="upload.headers" <el-upload ref="upload" :limit="1" accept=".xlsx, .xls" :headers="upload.headers"
@ -74,7 +74,7 @@
</div> </div>
<el-table v-loading="loading" :data="postList" @selection-change="handleSelectionChange" stripe> <el-table v-loading="loading" :data="postList" @selection-change="handleSelectionChange" stripe>
<el-table-column type="selection" width="55" align="center" /> <!-- <el-table-column type="selection" width="55" align="center" /> -->
<el-table-column label="序号" align="center"> <el-table-column label="序号" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ (scope.$index + 1) + (queryParams.current - 1) * queryParams.size }} {{ (scope.$index + 1) + (queryParams.current - 1) * queryParams.size }}

@ -41,9 +41,9 @@
<el-row> <el-row>
<el-col :span="8"> <el-col :span="8">
<el-form-item> <el-form-item>
<el-button type="primary" icon="el-icon-search" size="medium" <el-button type="primary" icon="el-icon-search"
@click="handleQuery">查询</el-button> @click="handleQuery">查询</el-button>
<el-button icon="el-icon-refresh" size="medium" @click="resetQuery"></el-button> <el-button icon="el-icon-refresh" @click="resetQuery"></el-button>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
@ -52,13 +52,9 @@
<!-- 表格内容区 --> <!-- 表格内容区 -->
<div class="tablebox"> <div class="tablebox">
<!-- 标签行 --> <!-- 标签行 -->
<div class="tablehead"> <!-- <div class="tablehead">
<div class="headtitle"><span>项目清单</span></div> <div class="headtitle"><span>项目清单</span></div>
<div class="headbtn"> </div> -->
<el-button type="primary" icon="el-icon-download" @click="importTemplate"></el-button>
<el-button type="primary" size="mini" @click="handleImport"></el-button>
</div>
</div>
<!-- 导入弹窗 --> <!-- 导入弹窗 -->
<el-dialog title="导入" :visible.sync="upload.open" width="400px" append-to-body> <el-dialog title="导入" :visible.sync="upload.open" width="400px" append-to-body>
<el-upload ref="upload" :limit="1" accept=".xlsx, .xls" :headers="upload.headers" <el-upload ref="upload" :limit="1" accept=".xlsx, .xls" :headers="upload.headers"
@ -79,15 +75,27 @@
<div class="tablebtntwo"> <div class="tablebtntwo">
<el-row :gutter="10" class="mb8"> <el-row :gutter="10" class="mb8">
<el-col :span="1.5"> <el-col :span="1.5">
<el-button type="primary" icon="el-icon-upload2" size="medium" <el-button
@click="handleExport">导出</el-button> type="primary"
@click="handleExport"
>全量导出</el-button>
</el-col> </el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button type="primary" size="medium" @click="handleExporttwo"> <el-button type="primary"
@click="handleExporttwo">
单片材料导出 单片材料导出
</el-button> </el-button>
</el-col> </el-col>
</el-row> </el-row>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" icon="el-icon-download" @click="importTemplate" >下载模板</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="primary" @click="handleImport"></el-button>
</el-col>
</el-row>
</div> </div>
<el-table v-loading="loading" :data="postList" @selection-change="handleSelectionChange" stripe> <el-table v-loading="loading" :data="postList" @selection-change="handleSelectionChange" stripe>
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
@ -117,15 +125,15 @@
statusMap[scope.row.status] }}</span> statusMap[scope.row.status] }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <el-table-column label="操作" align="center" fixed="right" class-name="small-padding fixed-width">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button size="medium" type="text" @click="getAdd(scope.row, 'fill')" <el-button type="text" @click="getAdd(scope.row, 'fill')"
v-if="statusMap[scope.row.status] === '待审核'">详情</el-button> v-if="statusMap[scope.row.status] === '待审核'">审核</el-button>
<el-button size="medium" type="text" @click="getAdd(scope.row, 'okay')" <el-button type="text" @click="getAdd(scope.row, 'okay')"
v-if="statusMap[scope.row.status] === '审核通过'">详情</el-button> v-if="statusMap[scope.row.status] === '审核通过'">编辑</el-button>
<el-button size="medium" type="text" @click="getAdd(scope.row, 'detail')" <el-button type="text" @click="getAdd(scope.row, 'detail')"
v-if="statusMap[scope.row.status] === '待填报'">详情</el-button> v-if="statusMap[scope.row.status] === '待填报'">详情</el-button>
<el-button size="medium" type="text" @click="handleDelete(scope.row)" <el-button type="text" @click="handleDelete(scope.row)"
style="color: #F25353;">删除</el-button> style="color: #F25353;">删除</el-button>
</template> </template>
</el-table-column> </el-table-column>
@ -354,6 +362,10 @@ export default {
}; };
</script> </script>
<style scoped> <style scoped>
.headtitle{
font-size: 1.25rem;
font-weight: 400;
}
.headerbox { .headerbox {
background-color: #fff; background-color: #fff;
border-radius: .5rem; border-radius: .5rem;
@ -383,5 +395,8 @@ export default {
.tablebtntwo { .tablebtntwo {
margin-top: 1rem; margin-top: 1rem;
margin-bottom: 1rem; margin-bottom: 1rem;
width: 100%;
display: flex;
justify-content: space-between;
} }
</style> </style>
Loading…
Cancel
Save