- <template>
- <!-- 项目信息 -->
- <div class="projectInformation">
- <div class="top">
- <el-form ref="queryFormRef" :model="form" v-show="showSearch">
- <el-row :gutter="20">
- <el-col :span="5">
- <el-form-item label="项目名称:" prop="projectName" class="formItem">
- <el-input v-model="form.projectName" placeholder="请输入项目名称" clearable style="width: 100%"></el-input>
- </el-form-item>
- </el-col>
- <el-col :span="4">
- <el-form-item label="项目类型:" prop="projectTypeId">
- <el-select v-model="form.projectTypeId" placeholder="请选择项目类型" style="width: 100%">
- <el-option label="全部" value="" />
- <el-option v-for="dict in projectTypes" :key="dict.id" :label="dict.projectTypeName" :value="dict.id" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="4">
- <el-form-item label="建设类别:" prop="buildCategory">
- <el-select v-model="form.buildCategory" placeholder="请选择建设类别" style="width: 100%">
- <el-option label="全部" value="" />
- <el-option v-for="dict in build_category" :key="dict.value" :label="dict.label" :value="dict.value" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="6.5">
- <el-form-item label="项目日期:" prop="time">
- <el-date-picker
- v-model="form.time"
- type="daterange"
- range-separator="-"
- start-placeholder="开始日期"
- end-placeholder="结束日期"
- value-format="YYYY-MM-DD"
- />
- </el-form-item>
- </el-col>
- <el-col :span="4.5">
- <el-form-item label="责任部门:" prop="chargeDepartment">
- <el-input v-model="form.chargeDepartment" placeholder="请输入责任部门" style="width: 100%"></el-input>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="5">
- <el-form-item label="项目库类型:" prop="projectLibraryType" class="formItem">
- <el-select v-model="form.projectLibraryType" placeholder="请选择项目库类型" style="width: 100%">
- <el-option label="全部" value="" />
- <el-option v-for="dict in project_library_type" :key="dict.value" :label="dict.label" :value="dict.value" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="4.5">
- <el-form-item>
- <el-button type="primary" icon="Search" @click="search"> 搜索</el-button>
- <el-button icon="Refresh" @click="resetQuery">重置</el-button>
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- </div>
-
- <card-list class="card-list" ref="cardListRef" />
-
- <el-row class="row">
- <el-button type="primary" plain icon="Plus" @click="openDialog({}, 'add')">新增项目</el-button>
- <el-button type="danger" plain icon="Delete" @click="batchDel">批量删除</el-button>
- <el-button type="primary" plain icon="Edit" @click="editSchedule">修改进度</el-button>
- <el-button type="primary" plain icon="Download" @click="Download">导出</el-button>
- <right-toolbar v-model:showSearch="showSearch" @queryTable="resetQuery"></right-toolbar>
- </el-row>
- <div class="table" ref="table_box">
- <el-table :data="tableData" v-loading="loading" stripe :max-height="430" ref="multipleTableRef">
- <el-table-column type="selection" width="55" />
- <el-table-column label="项目名称" prop="projectName" show-overflow-tooltip />
- <el-table-column label="项目编码" prop="projectNo" width="80" />
- <el-table-column label="数据来源" prop="projectSource" width="120">
- <template #default="{ row }">
- <dict-tag :options="project_data_sources" :value="row.projectSource" />
- </template>
- </el-table-column>
- <el-table-column label="建设类别" prop="buildCategory" width="80">
- <template #default="{ row }">
- <span>{{ findText('build_category', row.buildCategory) }}</span>
- </template>
- </el-table-column>
- <el-table-column label="是否豁免" prop="isProjectExempt" width="80">
- <template #default="{ row }">
- <span>{{ row.isProjectExempt == '1' ? '是' : '否' }}</span>
- </template>
- </el-table-column>
- <el-table-column label="项目库类型" prop="projectLibraryType" width="90">
- <template #default="{ row }">
- <span>{{ findText('project_library_type', row.projectLibraryType) }}</span>
- </template>
- </el-table-column>
- <el-table-column label="建设进度" prop="projectProgress" width="80" />
- <el-table-column label="项目起止日期" prop="projectTime" width="140" />
- <el-table-column label="填报时间" prop="createTime" width="160" />
- <el-table-column label="项目概况" prop="projectOverview" show-overflow-tooltip />
- <el-table-column label="操作" show-overflow-tooltip width="240">
- <template #default="{ row }">
- <el-button icon="View" type="primary" link @click="openDialog(row, 'view')">详情</el-button>
- <el-button type="warning" icon="Edit" link @click="openDialog(row, 'edit')">修改</el-button>
- <el-button type="danger" icon="Delete" link @click="del(row)">删除</el-button>
- </template>
- </el-table-column>
- </el-table>
- <pagination class="pagination" :total="total" v-model:page="pageNum" v-model:limit="pageSize" @pagination="getTableList" />
- </div>
- <el-dialog
- v-model="visible"
- :title="`${opts.text}项目`"
- :close-on-click-modal="false"
- style="height: 800px"
- width="70%"
- :before-close="close"
- >
- <operate
- ref="operateRef"
- v-if="['add', 'edit'].includes(opts.type)"
- :cur-row="curRow"
- :opts="opts"
- :types="projectTypes"
- :build-category="build_category"
- :project-library-type="project_library_type"
- :project-content-type="project_content_type"
- @close="close"
- />
- <detail
- :cur-row="curRow"
- :types="projectTypes"
- :build-category="build_category"
- :project-library-type="project_library_type"
- :project-content-type="project_content_type"
- v-else-if="opts.type === 'view'"
- />
- <template #footer v-if="opts.type !== 'view'">
- <div class="dialog-footer">
- <el-button type="primary" @click="handleOk">确 定</el-button>
- <el-button @click="close">取 消</el-button>
- </div>
- </template>
- </el-dialog>
- <el-dialog v-model="visible1" title="修改建设进度" :close-on-click-modal="false" width="40%" :before-close="dialogClose" class="dialog">
- <el-form ref="dialogRuleFormRef" :model="dialogForm" :rules="dialogRules" v-if="visible1">
- <el-form-item label="建设状态:" prop="buildStatus">
- <el-select v-model="dialogForm.buildStatus" placeholder="请选择建设状态" style="width: 100%">
- <el-option v-for="dict in build_status" :key="dict.value" :label="dict.label" :value="dict.value" />
- </el-select>
- </el-form-item>
- <el-form-item label="建设进度:" prop="projectProgress">
- <div style="display: flex; width: 100%">
- <el-slider v-model="dialogForm.projectProgress" style="flex: 1" />
- <span style="margin-left: 10px">{{ dialogForm.projectProgress + '%' }}</span>
- </div>
- </el-form-item>
- <el-form-item label="完成项目总投资(含主体工程)(万元):" prop="accomplishTotalInvest">
- <el-input v-model="dialogForm.accomplishTotalInvest" placeholder="请输入完成项目总投资" />
- </el-form-item>
- <el-form-item label="完成海绵相关投资(不含主体工程)(万元):" prop="accomplishSpongeInvest">
- <el-input v-model="dialogForm.accomplishSpongeInvest" placeholder="请输入完成海绵相关投资" />
- </el-form-item>
- <el-form-item label="建设过程中照片:" prop="underWay">
- <div class="upload">
- <ImageFileUpload
- listType="picture-card"
- :limit="10"
- :saveFileArr="constractionFlieList"
- refType="projectInfoNew"
- refField="constraction"
- :fileType="['png', 'jpg', 'jpeg']"
- />
- </div>
- </el-form-item>
- <el-form-item label="建设完成后照片:" prop="complete">
- <div class="upload">
- <ImageFileUpload
- listType="picture-card"
- :limit="10"
- :saveFileArr="postConstractionFlieList"
- refType="projectInfoNew"
- refField="postConstraction"
- :fileType="['png', 'jpg', 'jpeg']"
- />
- </div>
- </el-form-item>
- </el-form>
- <template #footer v-if="opts.type !== 'view'">
- <div class="dialog-footer">
- <el-button type="primary" @click="dialogSubmit">确 定</el-button>
- <el-button @click="dialogClose">取 消</el-button>
- </div>
- </template>
- </el-dialog>
- <el-dialog v-model="visible2" title="查看位置" :close-on-click-modal="false" width="800px">
- <MapPosition v-if="showMap" :isShowSearch="false" :isShowTool="false"></MapPosition>
- </el-dialog>
- </div>
- </template>
-
- <script setup>
- import { usePagination, useAdaption, useDicts } from '@/hooks';
- import CardList from './components/cardList.vue';
- import { optTextMap } from '@/utils/map';
- import operate from './operate.vue';
- import detail from './details.vue';
- import MapPosition from '@/components/Map/index.vue'; //地图选点获取经纬度位置组件
- import { required } from '@/utils/validate-helper';
- import { inheritAttr } from '@/utils/v3';
- import {
- getProjectInfoNewPage,
- projectTypeList,
- projectInfoNewDel,
- projectInfoNewDetail,
- updateProjectBuildStatus,
- } from '@/api/project/projectInformationNew';
- import bus from '@/bus';
- const { proxy } = getCurrentInstance();
- const { build_category, project_library_type, project_content_type, build_status, findText } = useDicts(proxy);
- const { project_data_sources } = proxy.useDict('project_data_sources');
- const showSearch = ref(true);
- const form = reactive({
- projectName: '',
- projectTypeId: '',
- buildCategory: '',
- time: '',
- chargeDepartment: '',
- projectLibraryType: '',
- });
-
- const params = computed(() => {
- const args = JSON.parse(JSON.stringify(form));
- const { time } = args;
- delete args.time;
- return {
- ...args,
- startTime: time?.[0] || '',
- endTime: time?.[1] || '',
- };
- });
-
- const dialogForm = reactive({
- projectNo: '',
- buildStatus: '',
- projectProgress: 0,
- accomplishTotalInvest: '',
- accomplishSpongeInvest: '',
- underWay: '',
- complete: '',
- });
-
- const dialogRules = reactive({
- buildStatus: required('建设状态'),
- projectProgress: required('建设进度'),
- accomplishTotalInvest: required('完成项目总投资'),
- accomplishSpongeInvest: required('完成海绵相关投资'),
- });
-
- const constractionFlieList = ref([]);
- const postConstractionFlieList = ref([]);
- const opts = reactive({
- type: '',
- text: '',
- });
- const visible = ref(false);
- const curRow = shallowRef({});
- const visible1 = ref(false);
- const checkedList = shallowRef([]);
- const projectTypes = ref([]);
- const visible2 = ref(false);
- const { pageNum, pageSize, tableData, total, loading, getTableList } = usePagination(getProjectInfoNewPage, params);
-
- const getProjectTypeList = async () => {
- const res = await projectTypeList({ status: '0' });
- if (res?.code !== 200) return;
- projectTypes.value = res?.data || [];
- };
-
- const search = () => {
- pageNum.value = 1;
- getTableList();
- };
- const resetQuery = () => {
- proxy.$refs.queryFormRef.resetFields();
- search();
- };
-
- const openDialog = (data, type) => {
- visible.value = true;
- opts.type = type;
- opts.text = optTextMap.get(type);
- curRow.value = data;
- curRow.value.analysisUsers1 = data.drainagePartition ? data.drainagePartition.split(',') : [];
- };
-
- const close = type => {
- visible.value = false;
- opts.type = '';
- opts.text = '';
- if (['edit', 'add'].includes(type)) {
- search();
- proxy.$refs.cardListRef.getData();
- }
- };
-
- const del = row => {
- proxy.$modal
- .confirm('是否确认删除?')
- .then(async () => {
- const res = await projectInfoNewDel(row.id);
- if (res?.code !== 200) return;
- proxy.$modal.msgSuccess('操作成功!');
- getTableList();
- proxy.$refs.cardListRef.getData();
- })
- .catch(() => {});
- };
-
- const editSchedule = async () => {
- const list = proxy.$refs.multipleTableRef.getSelectionRows();
- if (!list.length) return proxy.$modal.msgError('请选择一条数据!');
- if (list.length > 1) return proxy.$modal.msgError('只能选择一条数据!');
- visible1.value = true;
- checkedList.value = list;
- const res = await projectInfoNewDetail(list[0].projectNo);
- if (res?.code !== 200) return;
- console.log(res.data);
- inheritAttr(res.data, dialogForm);
-
- res.data.sysFileList = res.data.sysFileList || [];
- for (const item of res.data.sysFileList) {
- item.refType = 'projectInfoNew';
- }
- constractionFlieList.value = res.data.sysFileList.filter(item => item.refField === 'constraction');
- postConstractionFlieList.value = res.data.sysFileList.filter(item => item.refField === 'postConstraction');
- };
-
- const batchDel = () => {
- const checkedList = proxy.$refs.multipleTableRef.getSelectionRows();
- if (!checkedList.length) return proxy.$modal.msgError('请选择一条数据!');
- proxy.$modal
- .confirm('是否确认删除?')
- .then(async () => {
- const res = await projectInfoNewDel(checkedList.map(item => item.id).join());
- if (res?.code !== 200) return;
- proxy.$modal.msgSuccess('操作成功!');
- getTableList();
- proxy.$refs.cardListRef.getData();
- })
- .catch(() => {});
- };
-
- const handleOk = () => {
- proxy.$refs.operateRef.submit();
- };
-
- const dialogClose = () => {
- visible1.value = false;
- checkedList.value = [];
- };
-
- const dialogSubmit = () => {
- proxy.$refs.dialogRuleFormRef.validate(async (valid, fields) => {
- if (valid) {
- console.log('submit!', dialogForm);
- const sysFileSaveRequestList = [].concat(constractionFlieList.value, postConstractionFlieList.value);
- const res = await updateProjectBuildStatus({ projectNo: checkedList.value[0].projectNo, ...dialogForm, sysFileSaveRequestList });
- if (res?.code !== 200) return;
- proxy.$modal.msgSuccess('操作成功!');
- getTableList();
- dialogClose();
- } else {
- console.log('error submit!', fields);
- }
- });
- };
-
- //导出
- function Download() {
- proxy.$modal
- .confirm('是否确认导出?')
- .then(async () => {
- proxy.download('/business/projectInfoNew/export', {}, `项目信息${new Date().getTime()}.xlsx`);
- })
- .catch(() => {});
- }
-
- onMounted(() => {
- getTableList();
- getProjectTypeList();
- });
- </script>
-
- <style lang="scss" scoped>
- .projectInformation {
- padding: 20px;
- height: 90vh;
- display: flex;
- flex-direction: column;
- .top {
- // margin-bottom: 15px;
- flex-shrink: 0;
- }
- .card-list {
- flex-shrink: 0;
- }
- .table {
- flex: 1;
- :deep(.pagination) {
- margin-top: 0;
- margin-right: 10px;
- .el-pagination {
- right: 20px;
- }
- }
- }
- :deep(.formItem) {
- .el-form-item__label {
- width: 110px;
- word-break: keep-all;
- }
- }
- }
-
- .row {
- margin: 10px 0;
- }
-
- .upload {
- position: relative;
- .fileName {
- position: absolute;
- left: 0;
- top: 30px;
- white-space: nowrap;
- display: flex;
- align-items: center;
- .del {
- flex-shrink: 0;
- color: #f56c6c;
- cursor: pointer;
- margin-left: 10px;
- }
- }
-
- .imgBox {
- display: flex;
- flex-wrap: wrap;
- .img {
- margin-right: 10px;
- }
- }
- }
-
- .img {
- position: relative;
- width: 178px;
- height: 178px;
- img {
- width: 100%;
- height: 100%;
- }
- .mask {
- position: absolute;
- left: 0;
- right: 0;
- top: 0;
- bottom: 0;
- background-color: rgba(0, 0, 0, 0.5);
- display: none;
- .icon {
- position: absolute;
- left: 50%;
- top: 50%;
- transform: translate(-50%, -50%);
- color: #fff;
- }
- }
- &:hover {
- .mask {
- display: block;
- }
- }
- }
- </style>