ModelFormFileTransferOpt104.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515
  1. <!-- 文件传输窗口 -->
  2. <template>
  3. <el-dialog
  4. :title="comonentVar.modelTitle"
  5. :visible.sync="comonentVar.dialogVisible"
  6. :destroy-on-close="true"
  7. :close-on-click-modal="false"
  8. width="65%"
  9. top="20px"
  10. @close="modelOnClose"
  11. >
  12. <div class="model-form">
  13. <!-- label-width 设置了:label 和 input 就不会换行 -->
  14. <el-form ref="modelYaoKongOpt" label-width="30px">
  15. <el-tabs v-model="fileGetTabname" type="border-card">
  16. <el-tab-pane label="文件读取" name="tab2" style="text-align: center;">
  17. <el-row style="text-align: left;margin-bottom: 10px;">
  18. <el-col>
  19. <span>文件目录:<el-input
  20. v-model="getFileDir"
  21. class=""
  22. clearable
  23. placeholder="请输入文件目录"
  24. type="text"
  25. style="width:380px;margin-right: 2rem;"
  26. /></span>
  27. <el-button
  28. type="primary"
  29. class="dark-button"
  30. size="big"
  31. icon="el-icon-download"
  32. @click="getDeviceFileList()"
  33. >获取目录文件</el-button>
  34. <el-button class="light-button" icon="el-icon-refresh" size="big" @click="refreshFileList()">刷新</el-button>
  35. <el-button style="float: right;" class="light-button" icon="el-icon-add" size="big" @click="addFileRecord()">添加文件信息</el-button>
  36. </el-col>
  37. </el-row>
  38. <el-row>
  39. <div class="buttons" style="text-align: left;">
  40. <el-button
  41. class="dark-button"
  42. icon="el-icon-delete"
  43. size="small"
  44. :disabled="!showDel"
  45. @click="multDelete()"
  46. >批量删除</el-button>
  47. </div>
  48. </el-row>
  49. <el-row type="flex" style="float:left;width: 100%;margin-top: 10px;">
  50. <el-col>
  51. <div class="left-report">
  52. <!-- 表格 -->
  53. <el-table v-loading="isLoading2" :data="dbFileList" :height="tableHeight" @selection-change="handleSelectionChange">
  54. <el-table-column
  55. type="selection"
  56. />
  57. <!-- id隐藏不显示,作为操作数据依据 -->
  58. <el-table-column v-if="false" property="id" label="id" />
  59. <el-table-column property="name" label="文件名" width="260px" />
  60. <el-table-column property="size" label="大小(B)" width="100px" />
  61. <el-table-column property="updateRc" label="状态" width="150px" />
  62. <el-table-column property="percent" label="进度" width="80px" />
  63. <el-table-column property="updateTime" label="最后更新时间" width="160px" />
  64. <el-table-column
  65. label="操作"
  66. >
  67. <template slot-scope="scope">
  68. <el-upload
  69. v-if="scope.row.upload==true"
  70. :action="uploadFileUrl"
  71. :show-file-list="false"
  72. :auto-upload="true"
  73. accept="*"
  74. :data="{filename:uploadFileName}"
  75. :disabled="isUploadFileIng"
  76. :headers="uplaodHeader"
  77. :before-upload="(file) => updateActionUrl2(file,scope.row.id)"
  78. :on-success="uploadSuccess"
  79. style="float: left;margin-right: 20px;"
  80. >
  81. <el-button
  82. type="text"
  83. class="light-button"
  84. icon="el-icon-upload2"
  85. :disabled="isUploadFileIng"
  86. size="small"
  87. >上传文件</el-button>
  88. </el-upload>
  89. <a v-if="scope.row.download==true" style="float: left;margin-right: 20px;" target="new" :href="`/test/file/${scope.row.id}/bytes`"><el-button class="table-act" type="text" icon="el-icon-download" size="small">下载文件</el-button></a>
  90. <el-button v-if="scope.row.writeable==true" style="float: left;margin-right: 20px;" class="table-act" type="text" icon="el-icon-download" size="small" @click="sendFile(scope.row)">写文件</el-button>
  91. <el-button v-if="scope.row.readable==true" style="float: left;margin-right: 20px;" class="table-act" type="text" icon="el-icon-download" size="small" @click="readFile(scope.row)">读文件</el-button>
  92. <el-button v-if="scope.row.deletable==true" style="float: left;" class="table-act" type="text" icon="el-icon-delete" size="small" @click="deleteFile(scope.row)">删除</el-button>
  93. <!--<el-button v-if="scope.row.pos==null || scope.row.size==null || scope.row.pos==scope.row.size" class="table-act" type="text" icon="el-icon-delete" size="small" @click="deleteFile(scope.row)">删除</el-button>-->
  94. </template>
  95. </el-table-column>
  96. </el-table>
  97. </div>
  98. </el-col>
  99. </el-row>
  100. </el-tab-pane>
  101. </el-tabs>
  102. <el-tabs v-model="fileSendTabname" type="border-card" style="margin-top: 20px;">
  103. <el-tab-pane label="文件直接下发" name="tab3" style="text-align: center;">
  104. <el-row>
  105. <el-col>
  106. <el-upload
  107. ref="upload"
  108. :action="uploadFileUrl"
  109. :show-file-list="false"
  110. :auto-upload="false"
  111. accept="*"
  112. :disabled="isUploadFileIng"
  113. :on-change="changeUpload"
  114. :headers="uplaodHeader"
  115. :before-upload="updateActionUrl"
  116. :on-success="uploadSuccess"
  117. style="float: left;margin-right: 20px;"
  118. >
  119. <el-button
  120. type="primary"
  121. class="dark-button"
  122. icon="el-icon-upload2"
  123. :disabled="isUploadFileIng"
  124. size="big"
  125. >选择本地文件</el-button>
  126. </el-upload>
  127. <el-button
  128. type="primary"
  129. class="dark-button"
  130. size="big"
  131. :disabled="isUploadFileIng || !isSelectedFile"
  132. icon="el-icon-upload2"
  133. style="float: left;"
  134. @click="submitUpload"
  135. >上传文件</el-button>
  136. </el-col>
  137. </el-row>
  138. <el-row v-show="isSelectedFile" style="margin-top: 20px;">
  139. <el-col>
  140. <span class="sendFileName">文件名称:{{ selectFileName }}</span><span class="sendFileProcess"><span ref="sendFileProcess2" class="sendFileProcess2" /></span><span class="sendFileProcessNumber">{{ sendFileProcessNumber }}</span>
  141. </el-col>
  142. </el-row>
  143. </el-tab-pane>
  144. </el-tabs>
  145. </el-form>
  146. <div class="buttons" style="margin-top:20px;text-align: right;">
  147. <div class="cancel">
  148. <el-button class="lightButton" icon="el-icon-circle-close" size="big" @click="cancelForm">取消</el-button>
  149. </div>
  150. </div>
  151. </div>
  152. </el-dialog>
  153. </template>
  154. <script>
  155. import { mapGetters } from 'vuex'
  156. import {
  157. putData,
  158. postData,
  159. httpGet,
  160. delRecord
  161. } from '@/api/common-action'
  162. import { getToken } from '@/utils/auth'
  163. export default {
  164. name: 'ModelFormSample',
  165. // model-parames 模态框参数
  166. props: {
  167. modelParames: {
  168. type: Object,
  169. default: function() {
  170. return {}
  171. }
  172. },
  173. sampleData: {
  174. type: Array,
  175. default: function() {
  176. return []
  177. }
  178. }
  179. },
  180. data() {
  181. return {
  182. comonentVar: {
  183. modelTitle: '加载中...',
  184. dialogVisible: true
  185. },
  186. isLoading: false,
  187. isLoading2: false,
  188. getFileDir: '/', // 拉取文件的目录名称
  189. uploadFileUrl: '', // 文件上传地址
  190. fid: '',
  191. uploadFileName: '', // 上传的文件名称
  192. uploadSize: 0, // 上传文件的大小
  193. isUploadFileIng: false, // 文件是否在上传中
  194. isSendFileId: 0, // 文件是不是正在下发中
  195. isReadFileId: 0, // 文件是不是正在读取中
  196. isSelectedFile: false,
  197. fileGetTabname: 'tab2',
  198. fileSendTabname: 'tab3',
  199. selectFileName: '请先选择本地文件',
  200. sendFileProcessNumber: '0 %',
  201. deviceFileList: [],
  202. dbFileList: [],
  203. uplaodHeader: { 'Authorization': 'Bearer ' + getToken() },
  204. tableHeight: window.innerHeight * 0.5,
  205. fileUrl: '',
  206. multipleSelection: '',
  207. // 批量删除显示控制
  208. showDel: false
  209. }
  210. },
  211. computed: {
  212. ...mapGetters([
  213. 'roles'
  214. ])
  215. },
  216. created() {
  217. },
  218. mounted() {
  219. // 初始化
  220. this.$nextTick(() => {
  221. this.initFunctions()
  222. })
  223. },
  224. methods: {
  225. // 初始化
  226. async initFunctions() {
  227. this.comonentVar.modelTitle = '文件传输'
  228. // this.fileUrl = window.STATIC_CONFIG.proxyUrl
  229. this.getList()
  230. },
  231. // 多选按钮状态改变 handleSelectionChange
  232. handleSelectionChange(val) {
  233. // 选中行存入临时变量中
  234. this.multipleSelection = val
  235. console.log('handleSelectionChange val', val)
  236. // 批量删除按钮激活
  237. if (val.length > 0) this.showDel = true
  238. else this.showDel = false
  239. },
  240. // 关闭model时执行
  241. modelOnClose() {
  242. this.$emit('toggleModel', 'ModelFormFileTransferOpt104', false)
  243. },
  244. // 拉取设备文件列表
  245. getDeviceFileList() {
  246. if (this.isLoading) {
  247. return
  248. }
  249. this.isLoading = true
  250. const url = `/equip/file/${this.modelParames.curPlanId}/list`
  251. postData(url, 'name=' + this.getFileDir).then(res => {
  252. this.isLoading = false
  253. // 请求结果
  254. if (res == null || res.data == null || res.data === '') {
  255. return
  256. }
  257. this.getList()
  258. }).catch(rees => {
  259. this.isLoading = false
  260. })
  261. },
  262. getList() {
  263. if (this.isLoading2) {
  264. return
  265. }
  266. this.isLoading2 = true
  267. httpGet('/test/file/search?runnerId=' + this.modelParames.curPlanId).then(res => {
  268. this.isLoading2 = false
  269. const resLst = res.content
  270. if (resLst != null && resLst.length > 0) {
  271. for (let i = 0; i < resLst.length; i++) {
  272. resLst[i]['size'] = resLst[i]['size'] || 0
  273. if (resLst[i]['size'] === 0) {
  274. resLst[i]['pro'] = 0
  275. continue
  276. }
  277. resLst[i]['pro'] = Math.round((resLst[i]['pos'] || 0) * 1 / (resLst[i]['size'] || 0) * 1)
  278. }
  279. }
  280. this.dbFileList = resLst
  281. }).catch(res => {
  282. this.isLoading2 = false
  283. this.$message({
  284. message: res.message,
  285. type: 'error',
  286. offset: window.screen.height / 3
  287. })
  288. })
  289. },
  290. refreshFileList() {
  291. this.getList()
  292. },
  293. changeUpload(e) {
  294. this.isUploadFileIng = false
  295. this.isSelectedFile = true
  296. this.selectFileName = e.name
  297. this.uploadSize = e.size
  298. this.sendFileProcessNumber = '0 %'
  299. this.$refs.sendFileProcess2.style.width = 0 * (300 / 100) + 'px'
  300. },
  301. addFileRecord() {
  302. this.$prompt('文件名称', '文件信息', {
  303. inputAttrs: {
  304. maxlength: 50,
  305. placeholder: '请输入50个字符以内的文件名'
  306. }
  307. }).then((obj) => {
  308. // 确认
  309. const v = obj.value == null ? '' : obj.value.replace(/ /gi, '')
  310. if (v === '') {
  311. this.$message('文件名称不能为空')
  312. return
  313. }
  314. if (v.length > 50) {
  315. this.$message('文件名称不能超过50字符')
  316. return
  317. }
  318. // 先创建文件记录
  319. putData('/test/file', { 'runnerId': this.modelParames.curPlanId, 'name': v, 'size': 0 }).then(res => {
  320. this.$message('文件信息创添加成功')
  321. this.getList()
  322. }).catch(res => {
  323. this.$message({
  324. message: '文件信息添加失败:' + res.message,
  325. type: 'error',
  326. offset: window.screen.height / 3
  327. })
  328. })
  329. }).catch({
  330. // 取消
  331. })
  332. },
  333. submitUpload() {
  334. // 上传文件
  335. this.isUploadFileIng = true
  336. // 先创建文件记录
  337. putData('/test/file', { 'runnerId': this.modelParames.curPlanId, 'name': this.selectFileName, 'size': this.uploadSize }).then(res => {
  338. this.fid = res.id
  339. // /test/file/{id}/bytes
  340. // this.uploadFileUrl = window.STATIC_CONFIG.proxyUrl + '/test/file/' + fid + '/bytes' // 文件上传地址
  341. this.$refs.upload.submit()
  342. this.isUploadFileIng = false
  343. this.isSelectedFile = false
  344. }).catch(res => {
  345. this.isUploadFileIng = false
  346. this.isSelectedFile = false
  347. })
  348. },
  349. updateActionUrl() {
  350. return new Promise((r) => {
  351. this.$nextTick(() => {
  352. this.uploadFileUrl = '/test/file/' + this.fid + '/bytes' // 文件上传地址
  353. r()
  354. })
  355. })
  356. },
  357. updateActionUrl2(obj, id) {
  358. return new Promise((r) => {
  359. this.$nextTick(() => {
  360. this.uploadFileName = obj.name
  361. this.uploadFileUrl = '/test/file/' + id + '/bytes' // 文件上传地址
  362. r()
  363. })
  364. })
  365. },
  366. uploadSuccess() {
  367. this.$message({
  368. message: '文件上传成功',
  369. type: 'success',
  370. offset: window.screen.height / 3
  371. })
  372. this.getList()
  373. },
  374. async multDelete() {
  375. // 批量删除
  376. for (let i = 0; i < this.multipleSelection.length; i++) {
  377. const row = this.multipleSelection[i]
  378. let isOk = true
  379. await delRecord('/test/file/', row.id).then(res => {
  380. }).catch(res => {
  381. this.$message({
  382. message: res.message,
  383. type: 'error',
  384. offset: window.screen.height / 3
  385. })
  386. isOk = false
  387. })
  388. if (!isOk) {
  389. break
  390. }
  391. }
  392. this.getList()
  393. },
  394. deleteFile(row) {
  395. delRecord('/test/file/', row.id).then(res => {
  396. this.$message({
  397. message: '文件删除成功',
  398. type: 'success',
  399. offset: window.screen.height / 3
  400. })
  401. this.getList()
  402. }).catch(res => {
  403. this.$message({
  404. message: res.message,
  405. type: 'error',
  406. offset: window.screen.height / 3
  407. })
  408. })
  409. },
  410. downloadFile(row) {
  411. const url = `/test/file/${row.id}/bytes`
  412. httpGet(url).then(res => {
  413. console.log(res)
  414. }).catch(res => {
  415. })
  416. },
  417. readFile(row) {
  418. // 从设备上读取文件
  419. this.isReadFileId = row.id
  420. const url = `/equip/file/${this.modelParames.curPlanId}/get`
  421. postData(url, 'fileId=' + row.id).then(res => {
  422. this.$message({
  423. message: '文件' + row.name + '正在读取中,请等待读取完成',
  424. type: 'info',
  425. offset: window.screen.height / 3
  426. })
  427. const that = this
  428. setTimeout(() => {
  429. that.getList()
  430. }, 3000)
  431. }).catch(res => {
  432. this.isReadFileId = 0
  433. this.$message({
  434. message: res.message,
  435. type: 'error',
  436. offset: window.screen.height / 3
  437. })
  438. })
  439. },
  440. sendFile(row) {
  441. // 下发文件到设备
  442. this.isSendFileId = row.id
  443. const url = `/equip/file/${this.modelParames.curPlanId}/put`
  444. postData(url, 'fileId=' + row.id).then(res => {
  445. this.$message({
  446. message: '文件' + row.name + '正在下发中,请等待下发完成',
  447. type: 'info',
  448. offset: window.screen.height / 3
  449. })
  450. const that = this
  451. setTimeout(() => {
  452. that.getList()
  453. }, 3000)
  454. }).catch(res => {
  455. this.isSendFileId = 0
  456. this.$message({
  457. message: res.message,
  458. type: 'error',
  459. offset: window.screen.height / 3
  460. })
  461. })
  462. },
  463. // 表单取消按钮
  464. cancelForm() {
  465. if (this.isUploadFileIng) {
  466. this.$message({
  467. message: '文件正在下发中',
  468. type: 'info',
  469. offset: window.screen.height / 3
  470. })
  471. return
  472. }
  473. this.comonentVar.dialogVisible = false
  474. }
  475. }
  476. }
  477. </script>
  478. <style lang="scss">
  479. .sendFileName{
  480. float: left;
  481. overflow: hidden;
  482. text-overflow: ellipsis;
  483. width: 310px;
  484. white-space: nowrap;
  485. cursor: default;
  486. }
  487. .sendFileProcess {
  488. float: left;
  489. width: 300px;
  490. margin-top: 3px;
  491. background-color: #ccc;
  492. position: relative;
  493. border-radius: 5px;
  494. height: 10px;
  495. line-height: 10px;
  496. margin-left: 20px;
  497. .sendFileProcess2 {
  498. position: absolute;
  499. left: 0;
  500. top: 0;
  501. padding: 0;
  502. width: 0px;
  503. border-radius: 5px;
  504. height: 10px;
  505. line-height: 10px;
  506. background-color: blue;
  507. }
  508. }
  509. .sendFileProcessNumber{
  510. float: left;
  511. margin-left: 30px;
  512. font-weight: bold;
  513. }
  514. </style>