BatchInstruction.vue 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. <template>
  2. <div>
  3. <el-dialog class="batch-instruction" title="批量上传说明书" :visible.sync="visible" width="500px" :close-on-click-modal="false" append-to-body destroy-on-close :before-close="close" top="10vh">
  4. <template v-if="upload">
  5. <el-alert title="注意" type="warning" show-icon>
  6. <b>1. 同时只允许一个导入任务进行</b><br>
  7. <b>2. 在"开始更新专利说明书"步骤前不要关闭此弹出框</b><br>
  8. </el-alert>
  9. <div class="record">
  10. <el-timeline>
  11. <el-timeline-item v-for="(activity, index) in activityList" :type="activity.code === 1 ? 'primary' : 'danger'" :timestamp="activity.createTime">
  12. {{ activity.status }}
  13. </el-timeline-item>
  14. </el-timeline>
  15. </div>
  16. </template>
  17. <template v-else>
  18. <div>
  19. <el-form :model="ruleForm" :rules="rules" ref="ruleForm">
  20. <el-form-item label="文档类型" prop="type">
  21. <el-select v-model="ruleForm.type" class="width_100">
  22. <el-option label="公开文档" value="1"></el-option>
  23. <el-option label="授权文档" value="2"></el-option>
  24. </el-select>
  25. </el-form-item>
  26. <el-form-item label="导入文件" required>
  27. <el-upload class="upload-file" drag action="#" :auto-upload="false" :show-file-list="true" :on-change="onChange">
  28. <i :class="!ruleForm.file ? 'el-icon-upload' : 'el-icon-refresh'"></i>
  29. <div class="el-upload__text">将<span style="color: rgb(244, 87, 87);">压缩包</span>文件拖到此处,或<em>点击上传</em><span style="color: rgb(244, 87, 87);">压缩包</span></div>
  30. <div class="el-upload__tip" slot="tip"></div>
  31. </el-upload>
  32. </el-form-item>
  33. <el-form-item label="备注内容" prop="remark">
  34. <el-input v-model="ruleForm.remark" placeholder="请输入备注" type="textarea"></el-input>
  35. </el-form-item>
  36. </el-form>
  37. </div>
  38. <div slot="footer" class="dialog-footer">
  39. <el-button @click="close">取 消</el-button>
  40. <el-button type="primary" @click="submit" :loading="btnLoading">确 定</el-button>
  41. </div>
  42. </template>
  43. </el-dialog>
  44. </div>
  45. </template>
  46. <script>
  47. import { getFileMD5, createFileChunk } from "@/utils/file";
  48. import { renderSize, formatDate } from "@/utils";
  49. import { mapGetters } from "vuex";
  50. export default {
  51. data() {
  52. return {
  53. visible: false,
  54. btnLoading: false,
  55. ruleForm: {
  56. type: '1',
  57. file: null
  58. },
  59. rules: {
  60. type: [{ required: true, message: '请选择文档类型', trigger: 'change' },],
  61. },
  62. upload: false,
  63. activityList: []
  64. }
  65. },
  66. computed: {
  67. ...mapGetters(['webSocket', 'userinfo'])
  68. },
  69. created() {
  70. },
  71. methods: {
  72. renderSize,
  73. open() {
  74. this.webSocket.onmessage = (e) => {
  75. const { code, data, message } = JSON.parse(e.data)
  76. if (code === 900) {
  77. const status = `开始更新专利说明书(${data.index + 1}/${data.total})`
  78. if (this.activityList.length < 5) {
  79. this.activityList = [{
  80. status: status,
  81. code: 1,
  82. createTime: formatDate(new Date(), 'YYYY-MM-DD HH:mm:ss')
  83. }]
  84. this.upload = true
  85. } else {
  86. let record = this.activityList[4]
  87. record.status = status
  88. }
  89. if (data.index + 1 === data.total) {
  90. this.record('专利说明书更新完成')
  91. }
  92. } else if (code === 800) {
  93. this.$message.error(message)
  94. }
  95. }
  96. this.activityList = []
  97. this.upload = false
  98. this.visible = true
  99. },
  100. close() {
  101. this.visible = false
  102. this.ruleForm = {
  103. type: '1',
  104. file: null
  105. }
  106. this.$emit('close')
  107. },
  108. onChange(file, fileList) {
  109. this.ruleForm.file = file.raw
  110. },
  111. record(status, code = 1) {
  112. this.activityList.push({
  113. status: status,
  114. code: code,
  115. createTime: formatDate(new Date(), 'YYYY-MM-DD HH:mm:ss')
  116. })
  117. },
  118. uploadChunks(fileChunks, md5, index) {
  119. return new Promise((resolve, reject) => {
  120. if (index >= fileChunks.length) {
  121. resolve(true)
  122. }
  123. let formData = new FormData()
  124. formData.append('file', fileChunks[index].file)
  125. formData.append('md5', md5)
  126. formData.append('index', index)
  127. this.$api.uploadChunks(formData).then(async (response) => {
  128. let record = this.activityList[2]
  129. const status = `将分片上传至服务器(${index + 1}/${fileChunks.length})`
  130. if (record) {
  131. record.status = status
  132. } else {
  133. this.record(status)
  134. }
  135. resolve(this.uploadChunks(fileChunks, md5, index + 1))
  136. })
  137. })
  138. },
  139. submit() {
  140. if (!this.ruleForm.file) {
  141. this.$message.error('请选择文件')
  142. return false
  143. }
  144. this.$refs.ruleForm.validate((valid) => {
  145. if (valid) {
  146. // this.$showImportProgress(
  147. // {
  148. // data:this.ruleForm
  149. // }
  150. // )
  151. // return
  152. this.upload = true
  153. this.record('等待读取文件MD5')
  154. getFileMD5(this.ruleForm.file, async (md5) => {
  155. this.record('文件MD5:' + md5)
  156. let fileChunks = createFileChunk(this.ruleForm.file)
  157. await this.uploadChunks(fileChunks, md5, 0)
  158. this.record('等待服务器合并分片')
  159. const response = await this.$api.mergeChunks({ md5: md5, fileName: this.ruleForm.file.name })
  160. let params = {
  161. url: response.data,
  162. type: this.ruleForm.type,
  163. remark: this.ruleForm.remark
  164. }
  165. await this.$api.batchUploadPatentInstruction(params)
  166. this.record('开始更新专利说明书')
  167. })
  168. }
  169. })
  170. }
  171. }
  172. }
  173. </script>
  174. <style lang="scss">
  175. .batch-instruction {
  176. .el-timeline {
  177. padding: 10px !important;
  178. }
  179. .record {
  180. height: 600px;
  181. overflow-y: auto;
  182. margin-top: 10px;
  183. }
  184. }
  185. </style>