Sfoglia il codice sorgente

feat(check-standard): 新增保养标准批量导入功能

- 新增 BatchImportStandard 组件,支持通过 Excel 文件批量导入保养标准
- 新增批量导入接口和下载导入模板接口
- 在保养标准列表页添加批量导入和下载模板按钮
- 修复维修工时报表序号列在分页信息缺失时显示 NaN 的问题
dazhaxie 2 giorni fa
parent
commit
f57f8f64b1

+ 26 - 0
src/api/check/checkstandard.js

@@ -336,4 +336,30 @@ export function batchEditCheckStandard(parameter) {
     method: 'PUT',
     data: parameter
   })
+}
+
+/**
+ * 批量导入保养标准(仅新增)
+ * @param parameter FormData,file 字段
+ */
+export function importCheckStandardBatch(parameter) {
+  return axios({
+    url: '/check/standards/import/batch',
+    method: 'POST',
+    headers: {
+      'Content-Type': 'multipart/form-data;charset=UTF-8'
+    },
+    data: parameter
+  })
+}
+
+/**
+ * 下载保养标准批量导入模板
+ */
+export function downloadCheckStandardImportTemplate() {
+  return axios({
+    url: '/check/standards/import/template',
+    method: 'get',
+    responseType: 'blob'
+  })
 }

+ 18 - 0
src/views/check/checkstandard/CheckStandard.vue

@@ -76,6 +76,12 @@
         <a-button v-if="($auth('check-spot-standards-add') || $auth('check-polling-standards-add'))" type="primary"
           icon="plus" @click="handleBatchAdd">批量新增
         </a-button>
+        <a-button v-if="($auth('check-spot-standards-add') || $auth('check-polling-standards-add'))" type="primary"
+          icon="upload" @click="handleBatchImport">批量导入
+        </a-button>
+        <a-button v-if="($auth('check-spot-standards-add') || $auth('check-polling-standards-add'))"
+          icon="download" @click="handleDownloadTemplate">下载导入模板
+        </a-button>
         <!-- 隐藏批量调整标准按钮 -->
         <!--
         <a-button v-if="($auth('check-spot-standards-add') || $auth('check-polling-standards-add'))"
@@ -145,6 +151,7 @@
     <detail-standard-check-job ref="detailSbCheckJobModal" @ok="handleOk" />
     <base-form ref="baseModal" :check-type="checkType" @ok="handleOk" />
     <BatchBaseForm ref="batchBaseForm" :check-type="checkType" @ok="handleOk" />
+    <BatchImportStandard ref="batchImportModal" @ok="handleOk" />
     <detail ref="detailModal" :check-type="checkType" />
     <import-form-update ref="importModal" @ok="handleOk" />
     <BatchEditForm ref="batchEditForm" @ok="handleOk" />
@@ -155,6 +162,7 @@
 import { STable, Ellipsis } from '@/components'
 import BaseForm from './modules/BaseForm'
 import BatchBaseForm from './modules/BatchBaseForm'
+import BatchImportStandard from './modules/BatchImportStandard'
 import Detail from './modules/Detail'
 import BatchEditForm from './modules/BatchEditForm'
 import ImportFormUpdate from './modules/ImportFormUpdate'
@@ -164,6 +172,7 @@ import {
   updateCheckStandardNo,
   fetchCheckStandard,
   exportCheckStandard,
+  downloadCheckStandardImportTemplate,
 } from '@/api/check/checkstandard'
 import DetailStandardCheckJob from '@/views/check/checkjob/modules/DetailStandardCheckJob.vue'
 import { fetchSbTypeTree } from '@/api/sb/type'
@@ -179,6 +188,7 @@ export default {
     DetailStandardCheckJob,
     BatchBaseForm,
     BatchEditForm,
+    BatchImportStandard,
   },
   props: {
     /**
@@ -442,6 +452,14 @@ export default {
       const modal = this.$refs.batchBaseForm
       modal.base()
     },
+    handleBatchImport() {
+      this.$refs.batchImportModal.base()
+    },
+    handleDownloadTemplate() {
+      downloadCheckStandardImportTemplate().then((file) => {
+        this.BaseTool.UPLOAD.downLoadExportExcel(file)
+      })
+    },
     handleCopy(record) {
       fetchCheckStandard({ id: record.id }).then((res) => {
         const modal = this.$refs.baseModal

+ 115 - 0
src/views/check/checkstandard/modules/BatchImportStandard.vue

@@ -0,0 +1,115 @@
+<template>
+  <a-modal
+    title="批量导入保养标准"
+    :width="720"
+    :visible="visible"
+    :confirmLoading="confirmLoading"
+    @cancel="handleCancel"
+  >
+    <a-form :form="form">
+      <a-form-item
+        label="上传文件"
+        :labelCol="BaseTool.Constant.labelCol"
+        :wrapperCol="BaseTool.Constant.wrapperCol"
+      >
+        <a-upload
+          :fileList="fileList"
+          :multiple="false"
+          :remove="handleRemove"
+          :beforeUpload="beforeUpload"
+        >
+          <a-button><a-icon type="upload" />选择 Excel 文件</a-button>
+        </a-upload>
+      </a-form-item>
+      <a-form-item
+        :wrapperCol="BaseTool.Constant.wrapperCol"
+        :labelCol="{ span: 0 }"
+      >
+        <a-button type="link" icon="download" @click="doDownloadTemplate">下载导入模板</a-button>
+      </a-form-item>
+    </a-form>
+    <p style="color: red">
+      注意事项:<br />
+      1:一行对应一条保养标准,一台设备一个保养项类别需填一行<br />
+      2:设备编号(新号/旧号)、保养项类别名称必须已存在于系统中<br />
+      3:保养项类别下必须已配置保养项,执行人方式为“班组”时需填写执行班组名称<br />
+      4:只要有一行填写错误,将整批拒绝并提示错误行,不会导入任何数据<br />
+      5:示例行仅供参照,导入前请删除
+    </p>
+    <template slot="footer">
+      <a-button @click="handleCancel">关闭</a-button>
+      <a-button :loading="confirmLoading" type="primary" @click="save()">确定导入</a-button>
+    </template>
+  </a-modal>
+</template>
+
+<script>
+import { importCheckStandardBatch, downloadCheckStandardImportTemplate } from '@/api/check/checkstandard'
+
+export default {
+  name: 'BatchImportStandard',
+  data () {
+    return {
+      visible: false,
+      confirmLoading: false,
+      form: this.$form.createForm(this),
+      fileList: []
+    }
+  },
+  methods: {
+    base () {
+      this.visible = true
+      this.fileList = []
+      this.confirmLoading = false
+    },
+    beforeUpload (file) {
+      const reg = /\.(xls|xlsx)(\?.*)?$/
+      if (!reg.test(file.name)) {
+        this.$message.error('请上传正确的 Excel 文件')
+        return false
+      }
+      // 单文件:始终只保留最新选择的一个
+      this.fileList = [file]
+      return false
+    },
+    handleRemove (file) {
+      const index = this.fileList.indexOf(file)
+      const newFileList = this.fileList.slice()
+      newFileList.splice(index, 1)
+      this.fileList = newFileList
+    },
+    doDownloadTemplate () {
+      downloadCheckStandardImportTemplate().then((file) => {
+        this.BaseTool.UPLOAD.downLoadExportExcel(file)
+      })
+    },
+    save () {
+      if (this.fileList.length === 0) {
+        this.$message.info('请先选择要导入的文件')
+        return
+      }
+      const formData = new FormData()
+      formData.append('file', this.fileList[0], this.fileList[0].name)
+      this.confirmLoading = true
+      importCheckStandardBatch(formData)
+        .then((res) => {
+          this.confirmLoading = false
+          this.$message.success(res.data || '导入成功')
+          this.$emit('ok')
+          this.visible = false
+          this.fileList = []
+        })
+        .catch(() => {
+          // 整批拒绝:后端返回的错误提示由全局拦截器展示,此处仅复位按钮状态
+          this.confirmLoading = false
+        })
+    },
+    handleCancel () {
+      this.visible = false
+      this.confirmLoading = false
+      this.fileList = []
+      this.form.resetFields()
+    }
+  }
+}
+</script>

+ 7 - 3
src/views/report/repairworkhour/RepairWorkHour.vue

@@ -228,7 +228,9 @@ export default {
           const pageSize = parameter.pageSize || 20
           return Promise.resolve({
             rows: list.slice((pageNo - 1) * pageSize, pageNo * pageSize),
-            total: list.length
+            total: list.length,
+            // STable 用返回体的 pageNum 回填 localPagination.current,序号列依赖它,缺失会导致 NaN
+            pageNum: pageNo
           })
         }
         const query = this.buildQuery()
@@ -290,8 +292,10 @@ export default {
         width: '70px',
         customRender: (text, record, index) => {
           const pagination = this.$refs.table && this.$refs.table.localPagination
-          if (pagination) {
-            return `${(pagination.current - 1) * pagination.pageSize + index + 1}`
+          const current = pagination && pagination.current
+          const pageSize = pagination && pagination.pageSize
+          if (current && pageSize) {
+            return `${(current - 1) * pageSize + index + 1}`
           }
           return `${index + 1}`
         }