Sfoglia il codice sorgente

增加资产图片批量上传

liuyanpeng 2 anni fa
parent
commit
166b7ac2a7

+ 1 - 1
package.json

@@ -1,7 +1,7 @@
 {
   "name": "client-eam-v3",
   "description": "Leanwo Prodog Client",
-  "version": "3.0.60",
+  "version": "3.0.61",
   "author": "yangzhijie1488 <yangzhijie1488@163.com>",
   "scripts": {
     "dev": "cross-env webpack serve --config ./webpack.dev.js",

+ 40 - 0
src/common/image-src.js

@@ -0,0 +1,40 @@
+
+// 获取图片路径
+export function getImageSrc(className, imageName) {
+  var protocol = window.location.protocol;
+  // console.log('protocol:' + protocol);
+  var host = window.location.host;
+  // console.log('host:' + host);
+  var localhostPath = protocol + '//' + host;
+  var accountId = localStorage.getItem('#accountId') || 0;
+  if (imageName == null) {
+    return null;
+  }
+  if (imageName != null && imageName[0] == '/') {
+    return localhostPath + '/Files/' + accountId + '/Images/' + className + imageName;
+  } else {
+    return localhostPath + '/Files/' + accountId + '/Images/' + className + '/' + imageName;
+  }
+}
+  
+  
+// 获取略缩图图片路径
+export function getThumbnailImageSrc(className, imageName) {
+  var protocol = window.location.protocol;
+  // console.log('protocol:' + protocol);
+  var host = window.location.host;
+  // console.log('host:' + host);
+  var localhostPath = protocol + '//' + host;
+  //测试用
+  //var localhostPath = 'http://127.0.0.1:83';
+  console.log('localhostPath:' + localhostPath);
+  var accountId = localStorage.getItem('#accountId');
+  if (imageName == null) {
+    return null;
+  }
+  if (imageName != null && imageName[0] == '/') {
+    return localhostPath + '/Files/' + accountId + '/Images/' + className + '/thumbnail' + imageName;
+  } else {
+    return localhostPath + '/Files/' + accountId + '/Images/' + className + '/thumbnail/' + imageName;
+  }
+}

+ 24 - 3
src/components/AssetBasicSetting.vue

@@ -492,13 +492,18 @@
             :disabled="isdisable"
           />
         </div>
+        <div>
+          <a-button style="margin-bottom: 15px" @click="goDatax">
+            数据源编辑
+          </a-button>
+        </div>
         <div>
           <a-button
             style="margin-bottom: 15px"
             :disabled="isdisable"
             @click="initPostgreSQL"
           >
-            初始化资产监控PostgreSQL时序数据库
+            初始化资产监控PostgreSQL时序数据库
           </a-button>
         </div>
       </div>
@@ -875,6 +880,12 @@ export default {
       );
     },
 
+    // 跳转至数据源管理页面
+    goDatax: function () {
+      const url = this.getRootPath() + '/datax.html#/desktop/jdbcDatasource';
+      window.open(url);
+    },
+
     // 初始化资产监控PostgreSQL时序数据库
     initPostgreSQL: function () {
       const params = {
@@ -895,7 +906,11 @@ export default {
 
         success: function (data) {
           if (data.errorCode === 0) {
-            Notify.success('提示', '初始化资产监控PostgreSQL时序数据库成功!', 1500);
+            Notify.success(
+              '提示',
+              '初始化资产监控PostgreSQL时序数据库成功!',
+              1500,
+            );
           } else {
             Notify.error(data.errorMessage);
           }
@@ -908,7 +923,13 @@ export default {
     changeIsdisabled: function () {
       this.isdisable = !this.isdisable;
     },
-
+    // 获取主机地址
+    getRootPath: function () {
+      var protocol = window.location.protocol;
+      var host = window.location.host;
+      var localhostPath = protocol + '//' + host;
+      return localhostPath;
+    },
     getTotalNum: function (str) {
       if (str == undefined || str == '') {
         return;

+ 196 - 0
src/components/sonicAlbumUpload/CommonTable.vue

@@ -0,0 +1,196 @@
+<template>
+  <div class="tablePaganations">
+    <a-config-provider :locale="locale">
+      <a-table
+        class="ant-table-striped"
+        bordered
+        size="small"
+        height="1000px"
+        :loading="isLoading"
+        :data-source="dataSource"
+        :columns="columns"
+        :row-key="(record) => record.id"
+        :scroll="scrollValue"
+        :pagination="havePage ? pagination : false"
+        :row-selection="
+          isSelect
+            ? {
+              selectedRowKeys: state.selectedRowKeys,
+              onSelect: selectEvent,
+              onSelectAll: selectAllEvent,
+            }
+            : null
+        "
+        :row-class-name="
+          (_record, index) => (index % 2 === 1 ? 'table-striped' : null)
+        "
+        @resize-column="handleResizeColumn"
+      >
+        <template
+          v-for="(item, index) in renderArr"
+          #[item]="scope"
+          :key="index"
+        >
+          <slot :name="item" :scope="scope" v-bind="scope || {}" />
+        </template>
+      </a-table>
+    </a-config-provider>
+  </div>
+</template>
+  
+<script setup>
+import {
+  useSlots,
+  ref,
+  reactive,
+  defineProps,
+  defineEmits,
+  watch,
+  onMounted,
+  defineExpose,
+} from 'vue';
+import zhCN from 'ant-design-vue/lib/locale-provider/zh_CN';
+const locale = ref(zhCN);
+const props = defineProps({
+  dataSource: {
+    type: Object,
+    required: true,
+  },
+  columns: {
+    type: Object,
+    required: true,
+  },
+  isSelect: {
+    type: Boolean,
+  },
+  isLoading: {
+    type: Boolean,
+  },
+  total: {
+    type: Number,
+    default: 0,
+  },
+  havePage: {
+    type: Boolean,
+    default: true,
+  },
+  scrollValue: {
+    type: Object,
+    default: () => ({ y: 410 }),
+  },
+});
+
+//  选择数据
+const state = reactive({
+  selectedRows: [],
+  selectedRowKeys: [],
+});
+
+// 分页配置
+const pagination = reactive({
+  showQuickJumper: true,
+  current: 1,
+  pageSize: 20, // 默认每页显示数量
+  showSizeChanger: true, // 显示可改变每页数量
+  pageSizeOptions: ['20', '50', '100', '200', '300', '500'], // 每页数量选项值
+  showTotal: (total, range) =>
+    range[0] + '-' + range[1] + '条' + ' 共' + total + '条', // 显示总数
+  onShowSizeChange: (current, pageSize) => showSizeChange(current, pageSize),
+  onChange: (current, pageSize) => changePage(current, pageSize), //点击页码事件
+  total: props.total,
+});
+const emit = defineEmits(['pageParams', 'selectColumn']);
+
+// 改变每页数量时更新显示
+const showSizeChange = (current, pageSize) => {
+  setTimeout(() => {
+    pagination.current = 1;
+    emit('pageParams', pagination.current, pageSize);
+  });
+  pagination.pageSize = pageSize;
+};
+
+//点击页码事件
+const changePage = (current, size) => {
+  pagination.current = current;
+  emit('pageParams', pagination.current, size);
+};
+
+// 选择每一项操作
+const selectEvent = (record, selected, selectedRows) => {
+  if (selected) {
+    state.selectedRows.push(record);
+    state.selectedRowKeys.push(record.id);
+  } else {
+    let index = state.selectedRowKeys.indexOf(record.id);
+    if (index >= 0) {
+      state.selectedRows.splice(index, 1);
+      state.selectedRowKeys.splice(index, 1);
+    }
+  }
+  emit('selectColumn', state.selectedRows);
+};
+
+// 全选按钮操作
+const selectAllEvent = (selected, selectedRows, changeRows) => {
+  if (selected) {
+    state.selectedRows = state.selectedRows.concat(changeRows);
+    state.selectedRows.forEach(item => {
+      state.selectedRowKeys.push(item.id);
+    });
+  } else {
+    changeRows.forEach(item => {
+      state.selectedRows.forEach(row => {
+        if (item.id == row.id) {
+          state.selectedRows.splice(0, 1);
+        }
+      });
+      let index = state.selectedRowKeys.indexOf(item.id);
+      if (index >= 0) {
+        state.selectedRows.splice(index, 1);
+        state.selectedRowKeys.splice(index, 1);
+      }
+    });
+  }
+  emit('selectColumn', state.selectedRows);
+};
+// 伸缩列
+const handleResizeColumn = (w, col) => {
+  col.width = w;
+};
+// 清空选择
+const clear = () => {
+  state.selectedRowKeys = [];
+  state.selectedRows = [];
+  emit('selectColumn', state.selectedRows);
+};
+// 回到第一页
+const backFirstPage = () => {
+  pagination.current = 1;
+  emit('pageParams', pagination.current, pagination.pageSize);
+};
+defineExpose({ clear, backFirstPage });
+
+// 监听total变化
+watch(
+  props,
+  newData => {
+    pagination.total = newData.total;
+  },
+  { immediate: true, deep: true },
+);
+
+// 插槽的实例
+const slots = useSlots();
+const renderArr = Object.keys(slots);
+</script>
+<style scoped>
+.tablePaganations {
+  width: 100%;
+  margin-top: 20px;
+  margin-bottom: 20px;
+}
+.ant-table-striped :deep(.table-striped) td {
+  background-color: #fafafa;
+}
+</style>

+ 112 - 0
src/components/sonicAlbumUpload/ImagesUpload.vue

@@ -0,0 +1,112 @@
+<template>
+  <div style="height: 30px">
+    <a-upload
+      directory
+      :file-list="files.allFiles"
+      :show-upload-list="false"
+      :before-upload="beforeUpload"
+      @change="handleFolderUpload"
+    >
+      <a-button>
+        <upload-outlined />
+        选择资产图片文件夹
+      </a-button>
+    </a-upload>
+    <!-- <span v-if="imagesTotal > 0" class="ok">已上传<span style="color: #1890ff"> {{ imagesTotal }} </span>张</span> -->
+    <Loading v-if="loading" />
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive } from 'vue';
+import Common from '../../common/Common.js';
+import { message } from 'ant-design-vue';
+import { debounce, multipleImageUpload } from './configData.js';
+import { UploadOutlined } from '@ant-design/icons-vue';
+
+const loading = ref(false);
+const imageFiles = ref([]); // 图片文件列表
+const imagesTotal = ref(0); // 一个文件内图片数量
+const files = reactive({
+  fileList: [], // 用来操作文件数据
+  allFiles: [], // 文件夹中所有文件
+});
+// 文件上传事件(取图片文件)
+const handleFolderUpload = info => {
+  files.fileList.push(info.file);
+  const filesArray = Array.from(files.fileList);
+  imageFiles.value = filesArray.filter(file => file.type.includes('image'));
+  imagesTotal.value = imageFiles.value.length;
+  uploadImages();
+};
+
+const uploadImages = debounce(() => {
+  uploadFile();
+}, 600);
+
+// 图片上传请求
+const uploadFile = () => {
+  if (imagesTotal.value == 0) {
+    message.warning('请选择含有图片的文件夹!');
+  } else {
+    const formData = new FormData();
+    imageFiles.value.map(item => {
+      formData.append('imageFiles', item);
+    });
+    loading.value = true;
+    multipleImageUpload(formData).then(
+      successData => {
+        if (successData.errorCode === 0) {
+          message.success(
+            `上传成功!该文件夹共上传${imagesTotal.value}张资产图片。`,
+          );
+        } else {
+          message.warning(successData.errorMessage);
+        }
+        loading.value = false;
+        clearFile();
+      },
+      errorData => {
+        Common.processException(errorData);
+        loading.value = false;
+        clearFile();
+      },
+    );
+  }
+};
+
+// 禁止自带默认上传
+const beforeUpload = file => {
+  return false;
+};
+
+// 清空文件夹
+const clearFile = () => {
+  files.allFiles = [];
+  files.fileList = [];
+  imageFiles.value = [];
+  imagesTotal.value = 0;
+};
+</script>
+<style scoped>
+.files {
+  margin-right: 6px;
+  margin-left: 4px;
+}
+
+.upload-list-inline :deep(.ant-upload-list-item) {
+  float: left;
+  width: 200px;
+  margin-right: 8px;
+}
+
+.upload-list-inline [class*="-upload-list-rtl"] :deep(.ant-upload-list-item) {
+  float: right;
+}
+.ok {
+  margin-left: 8px;
+}
+.describe {
+  color: red;
+}
+</style>

+ 225 - 0
src/components/sonicAlbumUpload/configData.js

@@ -0,0 +1,225 @@
+import Common from '../../common/Common.js';
+
+export const imageColumns = [{
+  title: '图片名称',
+  key: 'imageName',
+  dataIndex: 'imageName',
+  width: 120,
+}, {
+  title: '上传时间',
+  key: 'imageTime',
+  dataIndex: 'imageTime',
+  width: 120,
+}, {
+  title: '图片大小',
+  key: 'imageSize',
+  dataIndex: 'imageSize',
+  width: 120,
+}];
+
+export const assetColumns = [{
+  title: '资产名称',
+  key: 'assetName',
+  dataIndex: 'assetName',
+  width: 120,
+}, {
+  title: '资产编号',
+  key: 'assetNo',
+  dataIndex: 'assetNo',
+  width: 120,
+}, {
+  title: '主图片',
+  key: 'mainImageName',
+  dataIndex: 'mainImageName',
+  width: 120,
+}, {
+  title: '其他图片',
+  key: 'otherImageName',
+  dataIndex: 'otherImageName',
+  width: 200,
+}];
+
+// 上传图片
+export const multipleImageUpload = params => {
+  var requestUrl = 'AssetInstanceResource/uploadImageFiles';
+  return new Promise((resolve, reject) => {
+    $.ajax({
+      url: Common.getApiURL(requestUrl),
+      type: 'post',
+      contentType: false,
+      processData: false,
+      data: params,
+      beforeSend: function (request) {
+        Common.addTokenToRequest(request);
+      },
+      success: function (data) {
+        resolve(data);
+      },
+      error: function (XMLHttpRequest, textStatus, errorThrown) {
+        reject(XMLHttpRequest);
+      },
+    });
+  });
+};
+// 根据名称查询临时图片
+export const queryImages = imageName => {
+  var requestUrl = `AssetInstanceResource/queryTemporaryFiles?imageName=${imageName}`;
+  return new Promise((resolve, reject) => {
+    $.ajax({
+      url: Common.getApiURL(requestUrl),
+      type: 'get',
+      dataType: 'json',
+      beforeSend: function (request) {
+        Common.addTokenToRequest(request);
+      },
+      success: function (data) {
+        resolve(data);
+      },
+      error: function (XMLHttpRequest, textStatus, errorThrown) {
+        reject(XMLHttpRequest);
+      },
+    });
+  });
+};
+
+// 根据名称删除图片
+export const deleteImage = params => {
+  var requestUrl = 'AssetInstanceResource/deleteImageFile';
+  return new Promise((resolve, reject) => {
+    $.ajax({
+      url: Common.getApiURL(requestUrl),
+      type: 'post',
+      contentType: 'application/json',
+      dataType: 'json',
+      data: JSON.stringify(params),
+      beforeSend: function (request) {
+        Common.addTokenToRequest(request);
+      },
+      success: function (data) {
+        resolve(data);
+      },
+      error: function (XMLHttpRequest, textStatus, errorThrown) {
+        reject(XMLHttpRequest);
+      },
+    });
+  });
+};
+// 测试上传excel
+export const testImportExcel = params => {
+  var requestUrl = 'AssetImageImportResource/testImportingTemporaryTables';
+  return new Promise((resolve, reject) => {
+    $.ajax({
+      url: Common.getApiURL(requestUrl),
+      type: 'post',
+      contentType: false,
+      processData: false,
+      data: params,
+      beforeSend: function (request) {
+        Common.addTokenToRequest(request);
+      },
+      success: function (data) {
+        resolve(data);
+      },
+      error: function (XMLHttpRequest, textStatus, errorThrown) {
+        reject(XMLHttpRequest);
+      },
+    });
+  });
+};
+// 正式上传excel
+export const importExcel = () => {
+  var requestUrl = 'AssetImageImportResource/importingTemporaryTables';
+  return new Promise((resolve, reject) => {
+    $.ajax({
+      url: Common.getApiURL(requestUrl),
+      type: 'post',
+      contentType: 'application/json',
+      dataType: 'json',
+      beforeSend: function (request) {
+        Common.addTokenToRequest(request);
+      },
+      success: function (data) {
+        resolve(data);
+      },
+      error: function (XMLHttpRequest, textStatus, errorThrown) {
+        reject(XMLHttpRequest);
+      },
+    });
+  });
+};
+// 查询临时表资产数据及图片
+export const queryAssetData = params => {
+  var requestUrl = 'AssetImageImportResource/queryAssetImageImport';
+  return new Promise((resolve, reject) => {
+    $.ajax({
+      url: Common.getApiURL(requestUrl),
+      type: 'post',
+      contentType: 'application/json',
+      dataType: 'json',
+      data: JSON.stringify(params),
+      beforeSend: function (request) {
+        Common.addTokenToRequest(request);
+      },
+      success: function (data) {
+        resolve(data);
+      },
+      error: function (XMLHttpRequest, textStatus, errorThrown) {
+        reject(XMLHttpRequest);
+      },
+    });
+  });
+};
+// 删除全部临时表资产数据及图片
+export const deleteAssetData = () => {
+  var requestUrl = 'AssetImageImportResource/deleteAssetImageImport';
+  return new Promise((resolve, reject) => {
+    $.ajax({
+      url: Common.getApiURL(requestUrl),
+      type: 'post',
+      contentType: 'application/json',
+      dataType: 'json',
+      beforeSend: function (request) {
+        Common.addTokenToRequest(request);
+      },
+      success: function (data) {
+        resolve(data);
+      },
+      error: function (XMLHttpRequest, textStatus, errorThrown) {
+        reject(XMLHttpRequest);
+      },
+    });
+  });
+};
+
+
+export const listClientCanAccess = ()=>{
+  var requestUrl = 'clientResourceV2/listClientCanAccess';
+
+  return new Promise((resolve, reject) => {
+    $.ajax({
+      url: Common.getApiURL(requestUrl),
+      type: 'get',
+      contentType: 'application/json',
+      beforeSend: function(request) {
+        Common.addTokenToRequest(request);
+      },
+      success: function(data) {
+        resolve(data);
+      },
+      error: function(XMLHttpRequest, textStatus, errorThrown) {
+        reject(XMLHttpRequest);
+      },
+    });
+  });
+};
+
+// 防抖函数
+export const debounce = (fn, wait = 1000) => {
+  let timer;
+  return function (...args) {
+    clearTimeout(timer);
+    timer = setTimeout(() => {
+      fn.call(this, args);
+    }, wait);
+  };
+};

+ 544 - 0
src/components/sonicAlbumUpload/index.vue

@@ -0,0 +1,544 @@
+<template>
+  <Navbar title="资产图片导入" />
+  <div class="container-box">
+    <div class="step">
+      <label>1. 选择公司</label>
+      <a-select
+        v-model:value="company"
+        style="width: 200px; margin: 0 12px"
+        :options="companies"
+      />
+      <a-button @click="downloadBtn">下载导入模板</a-button>
+    </div>
+    <div class="step">
+      <label style="margin-bottom: 12px">2. 上传资产图片Excel和图片文件</label>
+      <div>
+        <ImagesUpload />
+        <p class="pStyle">支持拓展名:.png .jpg .jpeg .gif</p>
+        <p class="pStyle">
+          <a @click="viewImage">查看上传的图片</a>
+        </p>
+        <div style="display: flex">
+          <a-upload
+            v-model:file-list="excelFiles"
+            :max-count="1"
+            :before-upload="beforeUpload"
+            :show-upload-list="{ showRemoveIcon: false }"
+            @change="excelFileChange"
+          >
+            <a-button>
+              <upload-outlined />
+              上传资产图片Excel
+            </a-button>
+          </a-upload>
+          <a-button
+            style="margin-left: 8px"
+            type="primary"
+            @click="testImport"
+          >
+            测试导入
+          </a-button>
+          <a-button
+            style="margin-left: 8px"
+            type="primary"
+            @click="importImageExcel"
+          >
+            正式导入
+          </a-button>
+        </div>
+        <p class="pStyle">支持拓展名:.xlsx</p>
+      </div>
+    </div>
+    <div class="step">
+      <label style="margin-bottom: 12px">3. 资产图片</label>
+      <ul class="siteList">
+        <li class="site">
+          <span class="labels">
+            <label>资产名称</label>
+          </span>
+          <a-input
+            v-model:value="assetName"
+            style="width: 70%; height: 30px"
+            placeholder="请输入资产名称"
+            @change="searchDatas"
+          />
+        </li>
+        <li class="site">
+          <span class="labels">
+            <label>资产编号</label>
+          </span>
+          <a-input
+            v-model:value="assetNo"
+            style="width: 70%; height: 30px"
+            placeholder="请输入资产编号"
+            @change="searchDatas"
+          />
+        </li>
+        <li class="site">
+          <span class="labels">
+            <label>图片状态</label>
+          </span>
+          <a-select
+            v-model:value="imageStatus"
+            style="width: 70%"
+            placeholder="请选择图片状态"
+            :options="imageAllStatus"
+            @change="searchDatas"
+          />
+        </li>
+      </ul>
+      <CommonTable
+        ref="table"
+        class="table"
+        :total="assetTotal"
+        :is-loading="isLoading"
+        :columns="assetImageColumns"
+        :data-source="assetImageDatas"
+        @page-params="getPageParams"
+        @select-column="selectColumn"
+      >
+        <template #bodyCell="{ column, record }">
+          <template v-if="column.key === 'mainImageName'">
+            <a-image
+              v-if="record.mainImageName !== ''"
+              :width="50"
+              :src="
+                getThumbnailImageSrc(record.className, record.mainImageName)
+              "
+            />
+          </template>
+          <template v-if="column.key === 'otherImageName'">
+            <template v-if="record.otherImageName !== ''">
+              <div style="display: flex">
+                <a-image
+                  v-for="item in record.otherImageNameArr"
+                  :key="item"
+                  :width="50"
+                  :src="getThumbnailImageSrc(record.className, item)"
+                />
+              </div>
+            </template>
+          </template>
+        </template>
+      </CommonTable>
+    </div>
+  </div>
+  <a-modal v-model:visible="downloadVisible" title="请选择下载数据范围">
+    <p>
+      全部数据:下载当前选择公司的全部资产图片数据。<a
+        @click="downloadReport(0)"
+      >下载</a>
+    </p>
+    <p>
+      无主图片:下载当前选择公司的资产中无主图片的数据。<a
+        @click="downloadReport(1)"
+      >下载</a>
+    </p>
+    <p>
+      无主图片或其他图片:下载当前选择公司中资产无主图片或无其他图片的数据。<a
+        @click="downloadReport(2)"
+      >下载</a>
+    </p>
+    <template #footer>
+      <a-button @click="downloadVisible = false">取消</a-button>
+    </template>
+  </a-modal>
+  <a-modal v-model:visible="imagesVisible" width="800px" title="已上传图片数据">
+    <div class="operation">
+      <a-button
+        danger
+        :disabled="deleteParams.length > 0 ? false : true"
+        @click="deleteImageData"
+      >
+        删除
+        {{ deleteParams.length > 0 ? `${deleteParams.length} 张资产图片` : "" }}
+      </a-button>
+      <a-input-search
+        v-model:value="imageNameParams"
+        placeholder="请输入图片名称进行搜索"
+        style="width: 30%"
+        @change="searchImage"
+        @search="searchImage"
+      />
+    </div>
+    <CommonTable
+      ref="table"
+      :total="total"
+      :is-select="true"
+      :columns="viewColumns"
+      :is-loading="isLoading"
+      :data-source="viewDatas"
+      @select-column="selectColumn"
+    >
+      <template #bodyCell="{ column, record }">
+        <template v-if="column.key === 'imageName'">
+          <a-image
+            v-if="record.imageName !== ''"
+            :width="50"
+            :src="getImageSrc(record.className, record.imageName)"
+          />
+          <span>{{ record.imageName }}</span>
+        </template>
+      </template>
+    </CommonTable>
+    <template #footer>
+      <a-button @click="imagesVisible = false">取消</a-button>
+    </template>
+  </a-modal>
+  <Loading v-if="loading" />
+</template>
+
+<script setup>
+import Common from '../../common/Common';
+import { Notify } from 'pc-component-v3';
+import { message } from 'ant-design-vue';
+import ImagesUpload from './ImagesUpload.vue';
+import CommonTable from './CommonTable.vue';
+import { UploadOutlined } from '@ant-design/icons-vue';
+import { ref, reactive, onMounted, onBeforeUnmount } from 'vue';
+import {
+  debounce,
+  queryImages,
+  importExcel,
+  deleteImage,
+  imageColumns,
+  assetColumns,
+  queryAssetData,
+  deleteAssetData,
+  testImportExcel,
+  listClientCanAccess,
+} from './configData.js';
+import { getImageSrc, getThumbnailImageSrc } from '../../common/image-src.js';
+
+const total = ref(0);
+const company = ref('');
+const table = ref(null);
+const assetNo = ref('');
+const assetName = ref('');
+const imageStatus = ref(0);
+const assetTotal = ref(0);
+const companies = ref([]);
+const viewDatas = ref([]);
+const excelFiles = ref([]);
+const loading = ref(false);
+const isLoading = ref(false);
+const deleteParams = ref([]);
+const assetImageDatas = ref([]);
+const imageNameParams = ref('');
+const imagesVisible = ref(false);
+const downloadVisible = ref(false);
+const viewColumns = ref(imageColumns);
+const assetImageColumns = ref(assetColumns);
+const excelFile = ref(null);
+const pager = reactive({
+  start: 0,
+  length: 20,
+});
+const imageAllStatus = reactive([
+  {
+    value: 0,
+    label: '全部',
+  },
+  {
+    value: 1,
+    label: '缺图片(无主图片或无其他图片)',
+  },
+  {
+    value: 2,
+    label: '有图片(有主图片或有其他图片)',
+  },
+]);
+
+// 打开下载模板模态框
+const downloadBtn = () => {
+  if (!company.value) {
+    message.warning('请先选择公司!');
+    return;
+  }
+  downloadVisible.value = true;
+};
+
+// 获取分页
+const getPageParams = (start, length) => {
+  pager.start = (start - 1) * length;
+  pager.length = length;
+  searchAsset();
+};
+
+// 查询回到第一页
+const searchDatas = debounce(() => {
+  table.value.backFirstPage();
+}, 600);
+
+// 查看上传的图片
+const viewImage = () => {
+  table.value.clear();
+  imagesVisible.value = true;
+  queryUploadImage();
+};
+
+// 查询上传图片接口
+const queryUploadImage = () => {
+  loading.value = true;
+  queryImages(imageNameParams.value).then(
+    successData => {
+      if (successData.errorCode == 0) {
+        successData.datas.forEach(item => {
+          item.id = item.imageName;
+        });
+        viewDatas.value = successData.datas;
+        total.value = viewDatas.value.length;
+      } else {
+        message.warning(successData.errorMessage);
+      }
+      loading.value = false;
+    },
+    errorData => {
+      Common.processException(errorData);
+      loading.value = false;
+    },
+  );
+};
+
+// 获取所选项的数据
+const selectColumn = rows => {
+  const names = [];
+  rows.forEach(item => {
+    names.push(item.imageName);
+  });
+  deleteParams.value = names;
+};
+
+// 删除上传的图片数据
+const deleteImageData = () => {
+  const params = JSON.parse(JSON.stringify(deleteParams.value));
+  loading.value = true;
+  deleteImage(params).then(
+    successData => {
+      if (successData.errorCode == 0) {
+        message.success('删除成功!');
+        queryUploadImage();
+      } else {
+        message.warning(successData.errorMessage);
+      }
+      deleteParams.value = [];
+      loading.value = false;
+    },
+    errorData => {
+      Common.processException(errorData);
+      loading.value = false;
+    },
+  );
+};
+
+// 根据图片名称查询图片信息
+const searchImage = debounce(() => {
+  queryUploadImage();
+}, 600);
+
+// 上传资产图片excel
+const excelFileChange = e => {
+  if (e.file.name.indexOf('.xlsx') == -1) {
+    excelFiles.value = [];
+    message.warning('请选择.xlsx格式的文件!');
+    return;
+  }
+  excelFile.value = e.file;
+};
+
+// 测试导入
+const testImport = () => {
+  if (excelFiles.value.length > 0) {
+    const formData = new FormData();
+    formData.append('imageSheet', excelFile.value);
+    loading.value = true;
+    testImportExcel(formData).then(
+      successData => {
+        if (successData.errorCode == 0) {
+          message.success('测试导入资产excel成功,请点击正式导入!');
+          searchAsset();
+        } else {
+          message.warning(successData.errorMessage);
+        }
+        loading.value = false;
+      },
+      errorData => {
+        Common.processException(errorData);
+        loading.value = false;
+      },
+    );
+  }
+};
+
+// 正式导入
+const importImageExcel = () => {
+  loading.value = true;
+  importExcel().then(
+    successData => {
+      if (successData.errorCode == 0) {
+        message.success('正式导入资产图片Excel成功!');
+        searchAsset();
+      } else {
+        message.warning(successData.errorMessage);
+      }
+      loading.value = false;
+    },
+    errorData => {
+      Common.processException(errorData);
+      loading.value = false;
+    },
+  );
+};
+
+// 查询资产数据
+const searchAsset = () => {
+  const params = {
+    assetNo: assetNo.value,
+    type: imageStatus.value,
+    assetName: assetName.value,
+    ...pager,
+  };
+  loading.value = true;
+  queryAssetData(params).then(
+    successData => {
+      if (successData.errorCode == 0) {
+        successData.datas.forEach(item => {
+          if (item.otherImageName !== '') {
+            item.otherImageNameArr = item.otherImageName.split(',');
+          }
+        });
+        assetImageDatas.value = successData.datas;
+        assetTotal.value = successData.total;
+      } else {
+        message.warning(successData.errorMessage);
+      }
+      loading.value = false;
+    },
+    errorData => {
+      Common.processException(errorData);
+      loading.value = false;
+    },
+  );
+};
+
+// 下载导入模板
+const downloadReport = type => {
+  const clientId = company.value;
+  let url;
+  if (type == 0) {
+    url = `/static/x-spreadsheet/index.html?processReportNo=20240308_095701&clientId=${clientId}`;
+  } else if (type == 1) {
+    url = `/static/x-spreadsheet/index.html?processReportNo=20240308_135134&clientId=${clientId}`;
+  } else {
+    url = `/static/x-spreadsheet/index.html?processReportNo=20240311_102330&clientId=${clientId}`;
+  }
+  window.open(url);
+};
+
+// 禁止自带默认上传
+const beforeUpload = file => {
+  return false;
+};
+
+onMounted(() => {
+  getClient();
+});
+
+// 关闭页面删除临时表数据
+onBeforeUnmount(() => {
+  loading.value = true;
+  deleteAssetData().then(
+    successData => {
+      loading.value = false;
+    },
+    errorData => {
+      Common.processException(errorData);
+      loading.value = false;
+    },
+  );
+});
+// 获取当前可访问公司
+const getClient = () => {
+  listClientCanAccess().then(
+    successData => {
+      if (successData.errorCode == 0) {
+        successData.datas.forEach(item => {
+          companies.value.push({ label: item.name, value: item.id });
+        });
+      } else {
+        Notify.error('错误', successData.errorMessage, false);
+      }
+    },
+    errorData => {
+      Common.processException(errorData);
+    },
+  );
+};
+</script>
+
+<style scoped>
+.step {
+  margin-bottom: 12px;
+}
+.step > label {
+  font-size: 16px;
+}
+.pStyle {
+  margin: 6px 0;
+  color: rgba(0, 0, 0, 0.65);
+}
+.table {
+  margin-top: 2px !important;
+}
+
+.siteList {
+  margin-bottom: 0 !important;
+  display: flex;
+  flex-wrap: wrap;
+  justify-content: space-between;
+}
+.siteList .site {
+  width: 300px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  position: relative;
+}
+.siteList > li {
+  margin-bottom: 8px;
+  margin-left: 0px;
+}
+
+@media (min-width: 500px) {
+  .siteList {
+    margin-left: 0;
+    margin-right: -20px;
+    justify-content: flex-start;
+  }
+  .siteList > li {
+    margin-right: 8px;
+  }
+}
+.labels {
+  width: 80px;
+  text-align: center;
+}
+.labels > label {
+  font-weight: 400 !important;
+}
+.operation {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+.tablePaganations {
+  margin-top: 6px;
+}
+:deep(.ant-image-img) {
+  width: 50px !important;
+  height: 50px !important;
+}
+.ant-image {
+  margin-right: 6px !important;
+}
+</style>

+ 2 - 0
src/index.js

@@ -42,6 +42,7 @@ import AssetLabelPrint from './components/customer/AssetLabelPrint.vue';
 import InventoryAssetInstanceSearch from './customer/InventoryAssetInstanceSearch.vue';
 import RunDataArchive from './components/customer/RunDataArchive.vue';
 import AssetRfidRecord from './components/rfidRecord/AssetRfidRecord.vue';
+import BatchUploadImages from './components/sonicAlbumUpload/index.vue';
 
 export {
   langZhCn,
@@ -85,4 +86,5 @@ export {
   InventoryAssetInstanceSearch,
   RunDataArchive,
   AssetRfidRecord,
+  BatchUploadImages,
 };

+ 4 - 0
src/router/index.js

@@ -35,6 +35,7 @@ const InventoryDataProcessing = () => import(/* webpackChunkName: "component-34"
 const AssetLabelPrint = () => import(/* webpackChunkName: "component-35" */ '../components/customer/AssetLabelPrint.vue');
 const RunDataArchive = () => import(/* webpackChunkName: "component-35" */ '../components/customer/RunDataArchive.vue');
 const AssetRfidRecord = () => import('../components/rfidRecord/AssetRfidRecord.vue');
+const BatchUploadImages = () => import('../components/sonicAlbumUpload/index.vue');
 
 const routes = [
 
@@ -299,6 +300,9 @@ const routes = [
   {
     path: '/eam/assetRfidRecord', component: AssetRfidRecord,
   },
+  {
+    path: '/eam/batchUploadImages', component: BatchUploadImages,
+  },
 ];