Newer
Older
KaiFengPC / src / views / project / projectInformation / operate.vue
@zhangdeliang zhangdeliang on 10 Jul 25 KB update
<template>
  <div class="operate">
    <el-form ref="operateRuleForm" :model="form" :rules="rules">
      <el-divider content-position="left">基本情况</el-divider>
      <el-row :gutter="20">
        <el-col :span="8">
          <el-form-item label="项目类别:" prop="projectTypeId">
            <el-select v-model="form.projectTypeId" placeholder="请选择项目类别" style="width: 100%" @change="projectTypeChange">
              <el-option v-for="dict in props.types" :key="dict.id" :label="dict.projectTypeName" :value="dict.id" />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="项目名称:" prop="projectName" class="formItem">
            <el-input v-model="form.projectName" placeholder="请输入项目名称" />
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="项目昵称:" prop="projectAbbreviation">
            <el-input v-model="form.projectAbbreviation" placeholder="请输入项目昵称" />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="20">
        <el-col :span="8">
          <el-form-item label="建设类别:" prop="buildCategory">
            <el-select v-model="form.buildCategory" placeholder="请选择建设类别" style="width: 100%">
              <el-option v-for="dict in props.buildCategory" :key="dict.value" :label="dict.label" :value="dict.value" />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="项目库类型:" prop="projectLibraryType" class="formItem">
            <el-select v-model="form.projectLibraryType" placeholder="请选择项目库类型" style="width: 100%">
              <el-option v-for="dict in props.projectLibraryType" :key="dict.value" :label="dict.label" :value="dict.value" />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="是否豁免项目:" prop="isProjectExempt">
            <el-select v-model="form.isProjectExempt" placeholder="请选择">
              <el-option label="是" value="1" />
              <el-option label="否" value="0" />
            </el-select>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="20">
        <el-col :span="8">
          <el-form-item label="排水分区:" prop="drainagePartition">
            <el-select
              v-model="form.analysisUsers1"
              placeholder="请选择排水分区(支持多选)"
              style="width: 100%"
              multiple
              collapse-tags
              collapse-tags-tooltip
            >
              <el-option v-for="dict in project_drainage_zone" :key="dict.value" :label="dict.label" :value="dict.value" />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="项目起止日期:" prop="time" class="formItem">
            <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="8">
          <el-form-item label="项目完工日期:" prop="time1">
            <el-date-picker type="date" v-model="form.projectCompleteTime" value-format="YYYY-MM-DD" start-placeholder="开始日期" />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="24">
        <el-col :span="16">
          <el-form-item label="项目位置:" prop="projectLocationName" style="width: 100%">
            <el-input v-model="form.projectLocationName" controls-position="right" placeholder="请输入">
              <template #append>
                <el-button type="primary" @click="visible = true">获取经纬度</el-button>
              </template>
            </el-input>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <!-- 用于应标,项目填报管理,不做字段存储 -->
          <el-form-item label="项目管理级别:" prop="projectLevel" style="width: 100%">
            <el-select v-model="form.projectLevel" placeholder="请选择" style="width: 100%">
              <el-option label="市海绵办综合管理" value="1" />
              <el-option label="市级项目管理" value="2" />
              <el-option label="区县项目管理" value="3" />
            </el-select>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-form-item label="规划条件:" prop="planCondition" style="width: 100%">
          <el-input type="textarea" v-model="form.planCondition" placeholder="请输入规划条件" />
        </el-form-item>
      </el-row>
      <el-row>
        <el-form-item label="项目概况:" prop="projectOverview" style="width: 100%">
          <el-input type="textarea" v-model="form.projectOverview" placeholder="请输入项目概况" resize="none" />
        </el-form-item>
      </el-row>
      <el-divider content-position="left">项目内容</el-divider>
      <el-card class="box-card" shadow="never" v-for="(item, index) in projectContentList">
        <template #header>
          <div class="card-header">
            <span>{{ item.label }}</span>
          </div>
        </template>
        <el-table :data="form[`list${index + 2}`]">
          <el-table-column v-for="it in item.list" :label="it.propertyName" :prop="it.propertyKey">
            <template #default="{ row }">
              <el-input v-model="row[it.propertyKey]" />
            </template>
          </el-table-column>
        </el-table>
      </el-card>
      <el-divider content-position="left">项目投资</el-divider>
      <el-row :gutter="20">
        <el-col :span="12">
          <el-form-item label="投资批复文件说明(已批复项目填写):" prop="investFileName">
            <el-input v-model="form.investFileName" placeholder="请输入投资批复文件说明" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <div class="upload">
            <ImageFileUpload
              listType="text"
              :limit="1"
              :saveFileArr="form.sysFileSaveRequestList"
              refType="projectInfoNew"
              refField="investmentApproval"
              :fileType="['pdf', 'doc', 'docx', 'xlsx', 'xls', 'txt']"
            />
          </div>
        </el-col>
      </el-row>
      <el-row :gutter="20">
        <el-col :span="8">
          <el-form-item label="项目总投资(含主体工程)(万元):" prop="totalInvest">
            <el-input v-model="form.totalInvest" placeholder="请输入项目总投资" />
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="地方政府投资(万元):" prop="govermentInvest">
            <el-input v-model="form.govermentInvest" placeholder="请输入地方政府投资" />
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="社会资本投入(万元):" prop="socialInvest">
            <el-input v-model="form.socialInvest" placeholder="请输入社会资本投入" />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="20">
        <el-col :span="8">
          <el-form-item label="项目运作模式:" prop="projectOperationPattern">
            <el-select v-model="form.projectOperationPattern" placeholder="请选择项目运作模式" style="width: 100%">
              <el-option v-for="dict in project_operation_pattern" :key="dict.value" :label="dict.label" :value="dict.value" />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="10">
          <el-form-item label="海绵相关投资(不含主体工程)(万元):" prop="spongeInvest">
            <el-input v-model="form.spongeInvest" placeholder="请输入海绵相关投资" />
          </el-form-item>
        </el-col>
      </el-row>
      <el-table :data="form.list1" v-if="projectInvestList[0]">
        <el-table-column v-for="it in projectInvestList[0].list" :label="it.propertyName" :prop="it.propertyKey">
          <template #default="{ row }">
            <el-input v-model="row[it.propertyKey]" />
          </template>
        </el-table-column>
      </el-table>
      <el-divider content-position="left">责任部门</el-divider>
      <el-row :gutter="20">
        <el-col :span="8">
          <el-form-item label="责任部门:" prop="chargeDepartment">
            <el-input v-model="form.chargeDepartment" placeholder="请输入责任部门" />
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="责任人:" prop="chargeUser">
            <el-input v-model="form.chargeUser" placeholder="请输入责任人" />
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="联系方式:" prop="phone">
            <el-input v-model="form.phone" placeholder="请输入联系方式" />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="20">
        <el-col :span="8">
          <el-form-item label="设计单位:" prop="designUnit">
            <el-select v-model="form.designUnit" placeholder="请选择设计单位" filterable style="width: 100%">
              <el-option v-for="dict in projectCompanyList3" :key="dict.id" :label="dict.unitName" :value="dict.id" />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="施工单位:" prop="constructUnit">
            <el-select v-model="form.constructUnit" filterable placeholder="请选择施工单位" style="width: 100%">
              <el-option v-for="dict in projectCompanyList" :key="dict.id" :label="dict.unitName" :value="dict.id" />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="运维单位:" prop="operationUnit">
            <el-select v-model="form.operationUnit" filterable placeholder="请选择运维单位" style="width: 100%">
              <el-option v-for="dict in projectCompanyList2" :key="dict.id" :label="dict.unitName" :value="dict.id" />
            </el-select>
          </el-form-item>
        </el-col>
      </el-row>
      <el-divider content-position="left">建设进度</el-divider>
      <el-row :gutter="20">
        <el-col :span="12">
          <el-form-item label="建设状态:" prop="buildStatus">
            <el-select v-model="form.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-col>
        <el-col :span="12">
          <el-form-item label="建设进度:" prop="projectProgress">
            <div style="display: flex; width: 100%">
              <el-slider v-model="form.projectProgress" style="flex: 1" />
              <span style="margin-left: 10px">{{ form.projectProgress + '%' }}</span>
            </div>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="20">
        <el-col :span="12">
          <el-form-item label="完成项目总投资(含主体工程)(万元):" prop="accomplishTotalInvest">
            <el-input v-model="form.accomplishTotalInvest" placeholder="请输入完成项目总投资" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="完成海绵相关投资(不含主体工程)(万元):" prop="accomplishSpongeInvest">
            <el-input v-model="form.accomplishSpongeInvest" placeholder="请输入完成海绵相关投资" />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="20">
        <el-col :span="12">
          <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-col>
        <el-col :span="12">
          <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-col>
      </el-row>
    </el-form>
    <!-- 位置选择弹窗 -->
    <el-dialog v-model="visible" title="选择位置" :close-on-click-modal="false" width="800px">
      <div class="mapBox">
        <MapBox
          v-if="visible"
          :isShowSearch="true"
          :isShowTool="false"
          :isSelectAddress="true"
          :previousPoint="previousPoint"
          :previousPointName="previousPointName"
          @getPlace="getAddress"
        ></MapBox>
      </div>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="visible = false">确 定</el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 规划分区 -->
    <el-dialog v-model="visibleArea" title="规划分区" :close-on-click-modal="false" width="1200px">
      <projectionMap @getProjectArea="getProjectArea"></projectionMap>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="visibleArea = false">确 定</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { required } from '@/utils/validate-helper';
import projectionMap from './projectionAreaMap.vue';
import { useDicts } from '@/hooks';
import MapBox from '@/components/Map';
import { inheritAttr } from '@/utils/v3';
import {
  getProjectCompanyList,
  getProjectItemDescriptionConfigList,
  projectInfoNewAdd,
  projectInfoNewById,
  getFileLIst,
  projectInfoNewEdit,
} from '@/api/project/projectInformationNew';
import ImageFileUpload from '@/components/ImageFileUpload';

const { proxy } = getCurrentInstance();
const emit = defineEmits(['close']);
const { drainage_partition, task_type, project_operation_pattern, build_status, project_drainage_zone } = useDicts(proxy);
const props = defineProps({
  curRow: {
    type: Object,
    default: () => ({}),
  },
  opts: {
    type: Object,
    default: () => ({}),
  },
  types: {
    type: Array,
    default: () => [],
  },
  buildCategory: {
    type: Array,
    default: () => [],
  },
  projectLibraryType: {
    type: Array,
    default: () => [],
  },
  projectContentType: {
    type: Array,
    default: () => [],
  },
});
const { curRow, opts } = props;
const form = reactive({
  projectLevel: '1',
  projectTypeId: '',
  projectName: '',
  projectAbbreviation: '',
  buildCategory: '',
  drainagePartition: '',
  time: '',
  projectCompleteTime: proxy.moment(new Date()).format('YYYY-MM-DD'),
  startTime: '',
  endTime: '',
  projectLocation: '',
  controlPartitionNum: '',
  isProjectExempt: '0',
  exemptFileSaveRequestList: [],
  projectLocationName: '',
  planCondition: '',
  projectLibraryType: '',
  taskType: '',
  projectOverview: '',
  investFileName: '',
  totalInvest: '',
  govermentInvest: '',
  socialInvest: '',
  projectOperationPattern: '',
  spongeInvest: '',
  chargeDepartment: '',
  chargeUser: '',
  phone: '',
  designUnit: '',
  constructUnit: '',
  operationUnit: '',
  buildStatus: '',
  projectProgress: 0,
  accomplishTotalInvest: '',
  accomplishSpongeInvest: '',
  underWay: '',
  complete: '',
  fileName: '',
  list1: [{}],
  list2: [{}],
  list3: [{}],
  list4: [{}],
  sysFileSaveRequestList: [],
});
const rules = reactive({
  // projectTypeId: required('项目类别'),
  // projectName: required('项目名称'),
  // buildCategory: required('建设类别'),
  // drainagePartition: required('汇水分区'),
  // time: required('项目日期'),
  // projectLocation: required('项目位置'),
  // isProjectExempt: required('豁免项目'),
  // planCondition: required('规划条件'),
  // projectLibraryType: required('项目库类型'),
  // taskType: required('任务类型'),
  // projectOverview: required('项目概况'),
  // investFileName: required('投资批复文件说明'),
  // totalInvest: required('项目总投资'),
  // govermentInvest: required('地方政府投资'),
  // socialInvest: required('社会资本投入'),
  // projectOperationPattern: required('项目运作模式'),
  // spongeInvest: required('海绵相关投资'),
  // chargeDepartment: required('责任部门'),
  // chargeUser: required('责任人'),
  // phone: required('联系方式'),
  // designUnit: required('设计单位'),
  // constructUnit: required('施工单位'),
  // operationUnit: required('运维单位'),
});

const projectCompanyList = ref([]);
const projectCompanyList2 = ref([]);
const projectCompanyList3 = ref([]);
const { unit_type } = proxy.useDict('unit_type');
const projectItemDescriptionConfigList = ref([]);
const projectContentList = ref([]);
const projectInvestList = ref([]);
const visible = ref(false);
const visibleArea = ref(false);
const constractionFlieList = ref([]);
const postConstractionFlieList = ref([]);
const previousPoint = ref('');
const previousPointName = ref('');
// 获取位置
function getAddress(val) {
  form.projectLocation = val.lonLat.join(','); //经纬度
  form.projectLocationName = val.caseAddress; //位置名称
  console.log('获取位置信息--', val, form.projectLocation);
}
// 获取分区
function getProjectArea(val) {
  form.controlPartitionNum = val.projectionAreaName;
}

const submit = () => {
  proxy.$refs.operateRuleForm.validate(async (valid, fields) => {
    if (valid) {
      console.log('submit!', form);

      if (form.isProjectExempt == '0') form.exemptFileSaveRequestList = [];
      const projectItemDescriptionSaveRequestList = [];
      for (let i = 0; i < projectContentList.value.length; i++) {
        const formList = form[`list${i + 2}`];
        const item = projectContentList.value[i];
        for (const it of item.list) {
          for (const key in formList[0]) {
            if (Object.hasOwnProperty.call(formList[0], key)) {
              const element = formList[0][key];
              if (key === it.propertyKey) {
                it.propertyValue = element;
              }
            }
          }
          projectItemDescriptionSaveRequestList.push(it);
        }
      }
      for (let j = 0; j < projectInvestList.value.length; j++) {
        const formList = form.list1;
        const item = projectInvestList.value[j];
        for (const it of item.list) {
          for (const key in formList[0]) {
            if (Object.hasOwnProperty.call(formList[0], key)) {
              const element = formList[0][key];
              if (key === it.propertyKey) {
                it.propertyValue = element;
              }
            }
          }
          projectItemDescriptionSaveRequestList.push(it);
        }
      }
      let sysFileSaveRequestList = JSON.parse(JSON.stringify(form.sysFileSaveRequestList));
      sysFileSaveRequestList = sysFileSaveRequestList.concat(constractionFlieList.value, postConstractionFlieList.value);

      form.drainagePartition = form.analysisUsers1.join(',');
      const params = {
        id: curRow?.id || '',
        ...form,
        startTime: form.time[0],
        endTime: form.time[1],
        projectItemDescriptionSaveRequestList,
        sysFileSaveRequestList,
      };
      delete params.list1;
      delete params.list2;
      delete params.list3;
      delete params.list4;
      delete params.time;
      let methed = '';
      if (params.id) {
        methed = projectInfoNewEdit;
      } else {
        methed = projectInfoNewAdd;
      }
      if (!methed) return;
      console.log(params, 'paramsparamsparams');

      const res = await methed(params);
      if (res?.code !== 200) return;
      proxy.$modal.msgSuccess('操作成功1!');
      emit('close', opts.type);
    } else {
      console.log('error submit!', fields);
    }
  });
};

const getProjectCompanyLists = async () => {
  const res = await getProjectCompanyList();
  if (res && res.code == 200) {
    let datas = res.data;
    // 施工单位
    projectCompanyList.value = datas.filter(item => item.unitType == unit_type.value[0].value);
    // 运维单位
    projectCompanyList2.value = datas.filter(item => item.unitType == unit_type.value[1].value);
    // 设计单位
    projectCompanyList3.value = datas.filter(item => item.unitType == unit_type.value[2].value);
  }
};

const getProjectItemDescriptionConfigLists = async () => {
  const res = await getProjectItemDescriptionConfigList({ projectTypeId: form.projectTypeId });
  if (res?.code !== 200) return;
  projectItemDescriptionConfigList.value = res?.data || [];
  console.log(projectItemDescriptionConfigList);
  projectContentList.value = props.projectContentType.slice(0, 3).map((item, i) => {
    const list = projectItemDescriptionConfigList.value.filter(it => it.projectContentType === item.value);
    const obj = {};
    for (const item of list) {
      obj[item.propertyKey] = '';
    }
    form[`list${i + 2}`] = [obj];
    return {
      list: JSON.parse(JSON.stringify(list)),
      label: item.label,
    };
  });
  projectInvestList.value = props.projectContentType.slice(3).map(item => {
    const list = projectItemDescriptionConfigList.value.filter(it => it.projectContentType === item.value);
    const obj = {};
    for (const item of list) {
      obj[item.propertyKey] = '';
    }
    form.list1 = [obj];
    return {
      list: JSON.parse(JSON.stringify(list)),
      label: item.label,
    };
  });
  console.log(projectContentList, projectInvestList);
};

const projectTypeChange = () => {
  form.list1 = [{}];
  form.list2 = [{}];
  form.list3 = [{}];
  form.list4 = [{}];
  getProjectItemDescriptionConfigLists();
};

const getDetail = async () => {
  const res = await projectInfoNewById(curRow.id);
  if (res?.code !== 200) return;
  console.log(res.data, 'ressssss');
  previousPoint.value = res.data.projectLocation;
  previousPointName.value = res.data.projectName;
  form.time = [res.data.startTime, res.data.endTime];
  inheritAttr(res.data, form);
  projectItemDescriptionConfigList.value = res?.data?.projectItemDescriptionList || [];
  console.log(projectItemDescriptionConfigList);
  projectContentList.value = props.projectContentType.slice(0, 3).map((item, i) => {
    const list = projectItemDescriptionConfigList.value.filter(it => it.projectContentType === item.value);
    const obj = {};
    for (const item of list) {
      obj[item.propertyKey] = item.propertyValue;
    }
    form[`list${i + 2}`] = [obj];
    return {
      list: JSON.parse(JSON.stringify(list)),
      label: item.label,
    };
  });
  projectInvestList.value = props.projectContentType.slice(3).map(item => {
    const list = projectItemDescriptionConfigList.value.filter(it => it.projectContentType === item.value);
    const obj = {};
    for (const item of list) {
      obj[item.propertyKey] = item.propertyValue;
    }
    form.list1 = [obj];
    return {
      list: JSON.parse(JSON.stringify(list)),
      label: item.label,
    };
  });
  getFileInfo(res.data.id, 'projectInfoNew', 'investmentApproval', data => {
    console.log(data);
    form.fileName = data?.[0]?.name || '';
    if (data?.[0]) {
      form.sysFileSaveRequestList = [data[0]];
    }
  });

  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 getFileInfo = async (id, refType, refField, callback) => {
  const res = await getFileLIst({ refId: id, refType, refField });
  if (res?.code !== 200) return;
  callback && callback(res.data);
};

onMounted(() => {
  getProjectCompanyLists();
  form.analysisUsers1 = props.curRow.analysisUsers1;
  if (curRow?.id) {
    getDetail();
  } else {
    if (props.types.length) {
      form.projectTypeId = props.types[0].id;
      getProjectItemDescriptionConfigLists();
    }
  }
});

defineExpose({
  submit,
});
</script>

<style lang="scss" scoped>
.operate {
  .box-card {
    margin-top: 10px;
    &:first-of-type {
      margin-top: 0;
    }
  }
  .tips {
    margin-left: 10px;
    line-height: 30px;
  }

  .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;
      }
    }
  }
}

.mapBox {
  height: 600px;
}
</style>