Newer
Older
HuangJiPC / src / pages / views / siteManage / siteManage.vue
@zhangdeliang zhangdeliang on 21 Jun 22 KB update
<template>
  <!-- 站点管理 -->
  <div class="siteManage">
    <div class="searchBox">
      <n-space>
        <n-input v-model:value="filterInfo.query.searchStr" clearable placeholder="请输入站点名称或编号" />
        <n-date-picker v-model:value="timeRange" type="datetimerange" clearable />
        <n-button type="primary" @click="handleClick('search')">
          <template #icon>
            <n-icon><Search /></n-icon>
          </template>
          搜索
        </n-button>
        <n-button type="primary" @click="handleClick('create')">
          <template #icon>
            <n-icon><Add /></n-icon>
          </template>
          新增
        </n-button>
      </n-space>
    </div>
    <div class="tableBox">
      <n-data-table
        ref="tableRef"
        :bordered="false"
        striped
        :max-height="700"
        :columns="columns"
        :data="tableData"
        :remote="true"
        :loading="tableLoading"
        :pagination="pagination"
      ></n-data-table>
    </div>
    <!-- 新增/编辑 -->
    <n-modal
      :title="dialogInfo.title[dialogInfo.type]"
      preset="card"
      :show-icon="false"
      :style="{ width: '600px' }"
      v-model:show="dialogInfo.visible"
    >
      <n-form
        v-if="dialogInfo.type === 'create' || dialogInfo.type === 'update'"
        ref="formRef"
        :label-width="150"
        :rules="formInfo.rules"
        :model="formInfo.data"
        label-placement="left"
      >
        <n-form-item label="站点名称:" path="stName">
          <n-input v-model:value="formInfo.data.stName" placeholder="请输入站点名称" style="width: 100%" />
        </n-form-item>
        <n-form-item label="站点编号:" path="stCode">
          <n-input
            v-model:value="formInfo.data.stCode"
            placeholder="请输入站点编号"
            style="width: 100%"
            :disabled="dialogInfo.type === 'update'"
          />
        </n-form-item>
        <n-form-item label="站点类型:" path="station">
          <n-select
            v-model:value="formInfo.data.station"
            filterable
            multiple
            :options="listTypeInfo['stationList']"
            placeholder="请选择站点类型"
          />
        </n-form-item>
        <n-form-item label="安装类型:" path="installationType">
          <n-select
            v-model:value="formInfo.data.installationType"
            filterable
            :options="installationdataList"
            placeholder="请选择安装类型"
          />
        </n-form-item>
        <n-form-item label="站点状态:" path="constructionStatus">
          <n-select v-model:value="formInfo.data.constructionStatus" :options="listTypeInfo['statusList']" />
        </n-form-item>
        <n-form-item label="知晓站点上线:" path="isKnow">
          <n-select v-model:value="formInfo.data.isKnow" :options="listTypeInfo['isKnowList']" />
        </n-form-item>
        <n-grid x-gap="12" :cols="2">
          <n-gi>
            <n-form-item label="经度:" path="lon">
              <n-input v-model:value="formInfo.data.lon" placeholder="请输入经度" style="width: 100%" />
            </n-form-item>
          </n-gi>
          <n-gi>
            <n-form-item label="纬度:" path="lat">
              <n-input v-model:value="formInfo.data.lat" placeholder="请输入纬度" style="width: 100%" />
            </n-form-item>
          </n-gi>
        </n-grid>
        <n-form-item label="站点安装位置:" path="address">
          <n-input v-model:value="formInfo.data.address" placeholder="请输入站点安装位置" style="width: 100%" />
        </n-form-item>
        <n-form-item label="安装负责人:" path="person">
          <n-input v-model:value="formInfo.data.person" placeholder="请输入安装负责人" style="width: 100%" />
        </n-form-item>
        <n-form-item label="视频监控地址:" path="videoPath">
          <n-select v-model:value="formInfo.data.videoPath" multiple :options="videoList" />
        </n-form-item>
        <n-form-item label="现场安装图片(最多3张):" path="fileList">
          <n-upload v-model:file-list="uploadList" accept=".jpg,.png,.jpeg,.svg,.gif" :max="3" list-type="image-card" @change="changeFile">
            点击上传
          </n-upload>
        </n-form-item>
      </n-form>
      <template #action>
        <n-space justify="end">
          <n-button @click="() => (dialogInfo.visible = false)">取消</n-button>
          <n-button type="primary" @click="handleClick('submit')" :loading="formInfo.loading">确定</n-button>
        </n-space>
      </template>
    </n-modal>
    <!-- 因子分配 -->
    <n-modal title="因子分配" preset="card" :show-icon="false" :style="{ width: '750px' }" v-model:show="dialogInfo.visible2">
      <n-transfer
        ref="transfer"
        v-model:value="transferValue"
        :options="transferOptions"
        source-title="可分配因子"
        target-title="已分配因子"
        filterable
        style="width: 700px"
      />
      <template #action>
        <n-space justify="end">
          <n-button @click="() => (dialogInfo.visible2 = false)">取消</n-button>
          <n-button type="primary" @click="() => (dialogInfo.visible2 = false)">确定</n-button>
        </n-space>
      </template>
    </n-modal>
  </div>
</template>

<script>
import { reactive, toRefs, ref, h, onMounted, computed, watch } from 'vue';
import { NButton, NTag, useMessage, useDialog } from 'naive-ui';
import { Search, Add } from '@vicons/ionicons5';
import { formatDate } from '@/utils/util';
import { useStore } from 'vuex';

import {
  stationbaseList,
  sysDicList,
  fileUpload,
  fileDelete,
  sysStationbaseSaveOrupdate,
  queryRiverWaterVideo,
  equipConfigList,
} from '@/services';

export default {
  components: {
    Search,
    Add,
  },
  setup() {
    const message = useMessage();
    const dialog = useDialog();
    const store = useStore();
    const formRef = ref();
    const allData = reactive({
      // 搜索相关
      filterInfo: {
        query: {
          searchStr: '',
          startDate: '',
          endDate: '',
          platformCode: '',
        },
      },
      uploadList: [],
      imageZG: [],
      videoList: [],
      timeRange: null,

      fileList: [], //图片列表
      installationdataList: [], //安装类型列表
      // 弹窗相关
      dialogInfo: {
        title: {
          create: '新增',
          update: '编辑',
        },
        type: '',
        visible: false,
        type2: '',
        visible2: false,
      },
      // 表单相关
      formInfo: {
        loading: false,
        data: {
          id: '',
          stName: '',
          stCode: '',
          station: [],
          stationType: '',
          installationType: '',
          constructionStatus: 0,
          isKnow: 1,
          address: '',
          person: '',
          videoPath: [],
          lat: '',
          lon: '',
          fileList: [],
        },
        rules: {
          stName: {
            required: true,
            message: '请输入站点名称',
            trigger: 'blur',
          },
          stCode: {
            required: true,
            message: '请输入站点编号',
            trigger: 'blur',
          },
          station: {
            type: 'array',
            required: true,
            message: '请选择站点类型',
            trigger: 'change',
          },
          installationType: {
            required: true,
            message: '请选择安装类型',
            trigger: 'change',
          },
          address: {
            required: true,
            message: '请输入安装位置',
            trigger: 'blur',
          },
          person: {
            required: true,
            message: '请输入安装负责人',
            trigger: 'blur',
          },
          lat: {
            required: true,
            message: '请输入纬度',
            trigger: 'blur',
          },
          lon: {
            required: true,
            message: '请输入经度',
            trigger: 'blur',
          },
        },
      },
      //表格
      columns: [
        {
          title: '站点编号',
          key: 'stCode',
          align: 'center',
          ellipsis: {
            tooltip: true,
          },
        },
        {
          title: '站点名称',
          key: 'stName',
          align: 'center',
          ellipsis: {
            tooltip: true,
          },
        },
        {
          title: '站点类型',
          key: 'stationType',
          align: 'center',
          render(row) {
            return h(
              NTag,
              {
                bordered: false,
              },
              {
                default: () => row.stationType || '--',
              }
            );
          },
        },
        {
          title: '安装类型',
          key: 'installationType',
          align: 'center',
          ellipsis: {
            tooltip: true,
          },
          render(row) {
            const arr = allData.installationdataList.filter((item) => item.value == row['installationType']);
            if (arr.length) {
              return h(
                NTag,
                {
                  bordered: false,
                },
                {
                  default: () => arr[0].label,
                }
              );
            }
          },
        },
        {
          title: '站点状态',
          key: 'constructionStatus',
          align: 'center',
          render(row) {
            return h(
              NTag,
              {
                bordered: false,
                color: {
                  color: 'transparent',
                  textColor: row.constructionStatus == 0 ? '#006DF7' : '#d03050',
                },
              },
              {
                default: () => (row.constructionStatus == 0 ? '启用' : '禁用'),
              }
            );
          },
        },
        {
          title: '站点上线',
          key: 'isKnow',
          align: 'center',
          render(row) {
            return h(
              NTag,
              {
                bordered: false,
                color: {
                  color: 'transparent',
                  textColor: row.isKnow == 1 ? '#006DF7' : '#d03050',
                },
              },
              {
                default: () => (row.isKnow == 1 ? '知晓' : '不知晓'),
              }
            );
          },
        },
        {
          title: '站点存储时间',
          key: 'ut',
          width: '150',
          align: 'center',
          ellipsis: {
            tooltip: true,
          },
        },

        {
          title: '安装人',
          key: 'person',
          align: 'center',
          ellipsis: {
            tooltip: true,
          },
        },
        {
          title: '关联因子',
          key: 'actions',
          width: '80',
          align: 'center',
          render(row) {
            const btn = allData.actionColumn2.map((item) => {
              return h(
                NButton,
                {
                  text: true,
                  size: item.size,
                  // style: {
                  //   margin: "10px",
                  // },
                  type: item.btnType,
                  onClick: () => handleClick(item.type, row),
                },
                { default: () => item.default }
              );
            });
            return btn;
          },
        },
        {
          title: '站点安装时间',
          key: 'createTime',
          width: '150',
          align: 'center',
          ellipsis: {
            tooltip: true,
          },
        },
        // {
        //   title: "创建人",
        //   key: "createUserName",
        //   align: "center",
        //   ellipsis: {
        //     tooltip: true,
        //   },
        // },
        // {
        //   title: "更新人",
        //   key: "updateUserName",
        //   align: "center",
        //   ellipsis: {
        //     tooltip: true,
        //   },
        // },
        {
          title: '更新时间',
          key: 'updateTime',
          align: 'center',
          ellipsis: {
            tooltip: true,
          },
        },
        {
          title: '创建时间',
          key: 'createTime',
          align: 'center',
          ellipsis: {
            tooltip: true,
          },
        },
        {
          title: '操作',
          key: 'actions',
          width: '80',
          align: 'center',
          render(row) {
            const btn = allData.actionColumn.map((item) => {
              return h(
                NButton,
                {
                  text: true,
                  size: item.size,
                  style: {
                    margin: '10px',
                  },
                  type: item.btnType,
                  onClick: () => handleClick(item.type, row),
                },
                { default: () => item.default }
              );
            });
            return btn;
          },
        },
      ],
      tableData: [],
      tableLoading: false,
      actionColumn: [
        {
          size: 'small',
          btnType: 'primary',
          type: 'update',
          default: '编辑',
        },
      ],
      actionColumn2: [
        {
          size: 'small',
          btnType: 'primary',
          type: 'Yinzi',
          default: '关联因子',
        },
      ],
      // 下拉数据集合
      listTypeInfo: {
        isKnowList: [
          { label: '不知晓', value: 0 },
          { label: '知晓', value: 1 },
        ],
        statusList: [
          { label: '启用', value: 0 },
          { label: '禁用', value: 1 },
        ],
        stationList: [],
      },
      // 穿梭框
      transferValue: ['DO', 'TP', 'pH', 'CODMN'],
      transferOptions: [],
    });
    allData.filterInfo.query.platformCode = computed(() => {
      return store.getters.platformCode;
    });
    //分页
    const paginationReactive = reactive({
      page: 1,
      pageSize: 10,
      showSizePicker: true,
      pageSizes: [10, 20, 50],
      showQuickJumper: true,
      pageCount: 0,
      itemCount: 0,
      onChange: (page) => {
        paginationReactive.page = page;
        getTableData();
      },
      onPageSizeChange: (pageSize) => {
        paginationReactive.pageSize = pageSize;
        paginationReactive.page = 1;
        getTableData();
      },
    });
    // 图片上传处理逻辑
    const changeFile = async (file) => {
      $loadingBar.start();
      if (file.event) {
        // 文件上传
        let formdata = new FormData();
        formdata.append('files', file.file.file);
        let config = {
          headers: { 'Content-Type': 'multipart/form-data' },
        };
        let res = await fileUpload(formdata, config);
        if (res && res.code === 200) {
          if (res.data.length > 0) {
            let datas = res.data[0];
            allData.formInfo.data.fileList.push(datas);
            let param = {
              fileNo: datas.fileNo,
              name: datas.fileOriginalName,
              url: datas.fileCloudStorageKey,
              status: 'success',
            };
            allData.imageZG.push(param);
          }
        } else {
          allData.uploadList = [];
          let param = {
            id: file.file.id,
            name: file.file.name,
            status: 'error',
          };
          allData.uploadList.push(param);
        }
        $loadingBar.finish();
      } else {
        // 文件删除,根据文件名进行匹配
        let fileIndex = null;
        allData.imageZG.map((item, index) => {
          if (file.file.name == item.name) {
            fileIndex = index;
          }
        });
        let fileNos = [];
        fileNos.push(allData.imageZG[fileIndex].fileNo);
        let res = await fileDelete(fileNos);
        if (res && res.code === 200) {
          allData.formInfo.data.fileList.splice(fileIndex, 1);
        }
      }
    };
    // 点击事件
    const handleClick = (type, row) => {
      switch (type) {
        // 搜索
        case 'search':
          paginationReactive.page = 1;
          getTableData();
          break;
        //新增
        case 'create':
          resetForm();
          allData.dialogInfo.type = type;
          allData.dialogInfo.visible = true;
          break;
        // 编辑
        case 'update':
          allData.dialogInfo.type = type;
          for (let key in row) {
            if (key in allData.formInfo.data) {
              if (key === 'stationType') {
                row[key] = row[key] !== null ? row[key].toString() : '';
              }
              if (key === 'installationType') {
                row[key] = `${row[key]}`;
              }
              if (key == 'videoPath') {
                if (!!!row[key]) row[key] = '';
                if (row[key] != '') {
                  row[key] = row[key].split(',');
                }
              }
              allData.formInfo.data[key] = row[key];
            }
          }
          // 处理站点类型
          let sitecodelist = [];
          let arr = row.stationType ? row.stationType.split('-') : [];
          if (arr.length) {
            for (var el in arr) {
              allData.listTypeInfo.stationList.forEach((item) => {
                if (arr[el] === item.label) {
                  sitecodelist.push(item.value);
                }
              });
            }
          }
          allData.formInfo.data.station = sitecodelist;
          // 图片文件默认填充
          allData.uploadList = [];
          allData.imageZG = [];
          if (row.fileList != null && row.fileList.length > 0) {
            row.fileList.map((item) => {
              let param = {
                id: item.id,
                name: item.tableName,
                status: 'finished',
                url: item.fileCloudStorageKey,
              };
              allData.uploadList.push(param);
            });
          }
          allData.imageZG = allData.uploadList;
          allData.dialogInfo.visible = true;
          break;
        // 表单提交
        case 'submit':
          formRef.value.validate((errors) => {
            if (!errors) {
              submit();
            } else {
              console.log(errors);
            }
          });
          break;
        case 'Yinzi':
          allData.dialogInfo.visible2 = true;
          break;
      }
    };
    // 表单提交
    async function submit() {
      // 处理站点类型
      let namelist = [];
      allData.formInfo.data.station.forEach((item) => {
        allData.listTypeInfo.stationList.forEach((site) => {
          if (item == site.value) {
            namelist.push(site.label);
          }
        });
      });
      allData.formInfo.data.stationType = namelist.join('-');
      if (typeof allData.formInfo.data.videoPath != 'string') {
        allData.formInfo.data.videoPath = allData.formInfo.data.videoPath.join();
      }
      let params = {
        data: allData.formInfo.data,
      };
      allData.formInfo.loading = true;
      let result = await sysStationbaseSaveOrupdate(params);
      allData.formInfo.loading = false;
      if (result.code === 1) {
        allData.dialogInfo.visible = false;
        if (allData.dialogInfo.type === 'create') {
          paginationReactive.page = 1;
        }
        getTableData();
      } else {
        return;
      }
    }
    // 重置表单
    function resetForm() {
      allData.formInfo.data = {
        id: '',
        stName: '',
        stCode: '',
        station: [],
        stationType: '',
        installationType: '',
        constructionStatus: 0,
        isKnow: 1,
        address: '',
        person: '',
        videoPath: null,
        lat: '',
        lon: '',
        fileList: [],
      };
    }
    // 获取表格数据
    const getTableData = async () => {
      allData.filterInfo.query.startDate = allData.timeRange ? formatDate(allData.timeRange[0]) : '';
      allData.filterInfo.query.endDate = allData.timeRange ? formatDate(allData.timeRange[1]) : '';
      let pramas = {
        current: paginationReactive.page,
        size: paginationReactive.pageSize,
        data: allData.filterInfo.query,
      };
      allData.tableLoading = true;
      let res = await stationbaseList(pramas);
      if (res && res.code == 1) {
        let datas = res.data;
        allData.tableData = res.data.list;
        paginationReactive.pageCount = datas.pages;
        paginationReactive.itemCount = datas.total;
      }
      allData.tableLoading = false;
    };
    //获取站点类型及安装类型列表
    const getDicType = async () => {
      let result = await sysDicList({ tableFieldType: 'installation_type' });
      if (result.code === 0) {
        allData.installationdataList = result.list.map((item) => {
          return {
            label: item.name,
            value: item.code,
          };
        });
      }
      let result1 = await sysDicList({ tableFieldType: 'site_type' });
      if (result1.code === 0) {
        allData.listTypeInfo.stationList = result1.list.map((item) => {
          return {
            label: item.name,
            value: item.code,
          };
        });
      }
    };
    // 获取摄像头列表
    const getAllVideo = async () => {
      let res = await queryRiverWaterVideo();
      if (res && res.code == 1) {
        allData.videoList = res.data;
      }
    };

    // 获取所有因子数据
    const getAllYinZiData = async () => {
      let pramas = {
        current: 1,
        size: 10000,
        data: { searchStr: '' },
      };
      let res = await equipConfigList(pramas);
      if (res && res.code == 1) {
        allData.transferOptions = [];
        res.data.list.forEach((element) => {
          allData.transferOptions.push({
            label: element.codeProperty + '  (' + element.codeAscll + ')',
            value: element.codeAscll,
          });
        });
      }
    };
    watch(
      () => allData.dialogInfo.visible,
      (val) => {
        if (!val) {
          allData.fileList = [];
          allData.dialogInfo.type = '';
        }
      }
    );
    onMounted(() => {
      getDicType();
      getAllVideo();
      getTableData();
      getAllYinZiData();
    });
    return {
      formRef,
      ...toRefs(allData),
      pagination: paginationReactive,
      getTableData,
      handleClick,
      getDicType,
      changeFile,
      getAllVideo,
    };
  },
};
</script>

<style lang="less" scoped>
.tableBox {
  margin-top: 10px;
}
</style>