ModelFormFileTransferOpt104.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  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="table-act"
  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-row style="float: right;">
  101. <!-- 分页 -->
  102. <div class="page-bar">
  103. <pagination
  104. background
  105. layout="pager"
  106. :limit="pageLimit"
  107. :total="paginationTotalElements"
  108. :current-page.sync="paginationNumber"
  109. :page="paginationNumber"
  110. @pagination="getList"
  111. />
  112. </div>
  113. </el-row>
  114. </el-tab-pane>
  115. </el-tabs>
  116. <el-tabs v-if="false" v-model="fileSendTabname" type="border-card" style="margin-top: 20px;">
  117. <el-tab-pane label="文件直接下发" name="tab3" style="text-align: center;">
  118. <el-row>
  119. <el-col>
  120. <el-upload
  121. ref="upload"
  122. :action="uploadFileUrl"
  123. :show-file-list="false"
  124. :auto-upload="false"
  125. accept="*"
  126. :disabled="isUploadFileIng"
  127. :on-change="changeUpload"
  128. :headers="uplaodHeader"
  129. :before-upload="updateActionUrl"
  130. :on-success="uploadSuccess"
  131. style="float: left;margin-right: 20px;"
  132. >
  133. <el-button
  134. type="primary"
  135. class="dark-button"
  136. icon="el-icon-upload2"
  137. :disabled="isUploadFileIng"
  138. size="big"
  139. >选择本地文件</el-button>
  140. </el-upload>
  141. <el-button
  142. type="primary"
  143. class="dark-button"
  144. size="big"
  145. :disabled="isUploadFileIng || !isSelectedFile"
  146. icon="el-icon-upload2"
  147. style="float: left;"
  148. @click="submitUpload"
  149. >上传文件</el-button>
  150. </el-col>
  151. </el-row>
  152. <el-row v-show="isSelectedFile" style="margin-top: 20px;">
  153. <el-col>
  154. <span class="sendFileName">选择的文件名称:{{ selectFileName }}</span><span v-if="false" class="sendFileProcess"><span v-if="false" ref="sendFileProcess2" class="sendFileProcess2" /></span><span v-if="false" class="sendFileProcessNumber">{{ sendFileProcessNumber }}</span>
  155. </el-col>
  156. </el-row>
  157. </el-tab-pane>
  158. </el-tabs>
  159. </el-form>
  160. <div class="buttons" style="margin-top:20px;text-align: right;">
  161. <div class="cancel">
  162. <el-button class="lightButton" icon="el-icon-circle-close" size="big" @click="cancelForm">取消</el-button>
  163. </div>
  164. </div>
  165. </div>
  166. </el-dialog>
  167. </template>
  168. <script>
  169. import { mapGetters } from 'vuex'
  170. import {
  171. putData,
  172. postData,
  173. httpGet,
  174. delRecord
  175. } from '@/api/common-action'
  176. import { getToken } from '@/utils/auth'
  177. import Pagination from '@/components/Pagination'
  178. export default {
  179. name: 'ModelFormSample',
  180. components: { Pagination },
  181. // model-parames 模态框参数
  182. props: {
  183. modelParames: {
  184. type: Object,
  185. default: function() {
  186. return {}
  187. }
  188. },
  189. sampleData: {
  190. type: Array,
  191. default: function() {
  192. return []
  193. }
  194. }
  195. },
  196. data() {
  197. return {
  198. comonentVar: {
  199. modelTitle: '加载中...',
  200. dialogVisible: true
  201. },
  202. pageLimit: 20,
  203. paginationNumber: 1,
  204. // 一共多少条
  205. paginationTotalElements: 0,
  206. isLoading: false,
  207. isLoading2: false,
  208. getFileDir: '/', // 拉取文件的目录名称
  209. uploadFileUrl: '', // 文件上传地址
  210. fid: '',
  211. uploadFileName: '', // 上传的文件名称
  212. uploadSize: 0, // 上传文件的大小
  213. isUploadFileIng: false, // 文件是否在上传中
  214. isSendFileId: 0, // 文件是不是正在下发中
  215. isReadFileId: 0, // 文件是不是正在读取中
  216. isSelectedFile: false,
  217. fileGetTabname: 'tab2',
  218. fileSendTabname: 'tab3',
  219. selectFileName: '请先选择本地文件',
  220. sendFileProcessNumber: '0 %',
  221. deviceFileList: [],
  222. dbFileList: [],
  223. uplaodHeader: { 'Authorization': 'Bearer ' + getToken() },
  224. tableHeight: window.innerHeight * 0.5,
  225. fileUrl: '',
  226. multipleSelection: '',
  227. // 批量删除显示控制
  228. showDel: false
  229. }
  230. },
  231. computed: {
  232. ...mapGetters([
  233. 'roles'
  234. ])
  235. },
  236. created() {
  237. },
  238. mounted() {
  239. // 初始化
  240. this.$nextTick(() => {
  241. this.initFunctions()
  242. })
  243. },
  244. methods: {
  245. // 初始化
  246. async initFunctions() {
  247. this.comonentVar.modelTitle = '文件传输'
  248. // this.fileUrl = window.STATIC_CONFIG.proxyUrl
  249. this.getList()
  250. },
  251. // 多选按钮状态改变 handleSelectionChange
  252. handleSelectionChange(val) {
  253. // 选中行存入临时变量中
  254. this.multipleSelection = val
  255. console.log('handleSelectionChange val', val)
  256. // 批量删除按钮激活
  257. if (val.length > 0) this.showDel = true
  258. else this.showDel = false
  259. },
  260. // 关闭model时执行
  261. modelOnClose() {
  262. this.$emit('toggleModel', 'ModelFormFileTransferOpt104', false)
  263. },
  264. // 拉取设备文件列表
  265. getDeviceFileList() {
  266. if (this.isLoading) {
  267. return
  268. }
  269. this.isLoading = true
  270. const url = `/equip/file/${this.modelParames.curPlanId}/list`
  271. postData(url, 'name=' + this.getFileDir).then(res => {
  272. this.isLoading = false
  273. // 请求结果
  274. if (res == null || res.data == null || res.data === '') {
  275. return
  276. }
  277. this.getList()
  278. }).catch(rees => {
  279. this.isLoading = false
  280. })
  281. },
  282. getList(pageObj) {
  283. if (this.isLoading2) {
  284. return
  285. }
  286. // 翻页时pageObj对象才会有值,属性分别为page和limit
  287. if (pageObj == null) {
  288. pageObj = {
  289. page: 0,
  290. limit: this.pageLimit
  291. }
  292. this.paginationNumber = 0
  293. } else {
  294. this.pageLimit = pageObj.limit
  295. }
  296. this.isLoading2 = true
  297. httpGet('/test/file/search?page=' + pageObj.page + '&size=' + pageObj.limit + '&runnerId=' + this.modelParames.curPlanId).then(res => {
  298. this.isLoading2 = false
  299. const resLst = res.content
  300. if (resLst != null && resLst.length > 0) {
  301. for (let i = 0; i < resLst.length; i++) {
  302. resLst[i]['size'] = resLst[i]['size'] || 0
  303. if (resLst[i]['size'] === 0) {
  304. resLst[i]['pro'] = 0
  305. continue
  306. }
  307. resLst[i]['pro'] = Math.round((resLst[i]['pos'] || 0) * 1 / (resLst[i]['size'] || 0) * 1)
  308. }
  309. }
  310. this.dbFileList = resLst
  311. this.paginationTotalElements = res.totalElements * 1
  312. this.paginationNumber = res.number * 1 + 1
  313. }).catch(res => {
  314. this.isLoading2 = false
  315. this.$message({
  316. message: res.message,
  317. type: 'error',
  318. offset: window.screen.height / 3
  319. })
  320. })
  321. },
  322. refreshFileList() {
  323. this.getList()
  324. },
  325. changeUpload(e) {
  326. this.isUploadFileIng = false
  327. this.isSelectedFile = true
  328. this.selectFileName = e.name
  329. this.uploadSize = e.size
  330. this.sendFileProcessNumber = '0 %'
  331. this.$refs.sendFileProcess2.style.width = 0 * (300 / 100) + 'px'
  332. },
  333. addFileRecord() {
  334. this.$prompt('文件名称', '文件信息', {
  335. inputAttrs: {
  336. maxlength: 50,
  337. placeholder: '请输入50个字符以内的文件名'
  338. }
  339. }).then((obj) => {
  340. // 确认
  341. const v = obj.value == null ? '' : obj.value.replace(/ /gi, '')
  342. if (v === '') {
  343. this.$message('文件名称不能为空')
  344. return
  345. }
  346. if (v.length > 50) {
  347. this.$message('文件名称不能超过50字符')
  348. return
  349. }
  350. // 先创建文件记录
  351. putData('/test/file', { 'runnerId': this.modelParames.curPlanId, 'name': v, 'size': 0 }).then(res => {
  352. this.$message('文件信息创添加成功')
  353. this.getList()
  354. }).catch(res => {
  355. this.$message({
  356. message: '文件信息添加失败:' + res.message,
  357. type: 'error',
  358. offset: window.screen.height / 3
  359. })
  360. })
  361. }).catch({
  362. // 取消
  363. })
  364. },
  365. submitUpload() {
  366. // 上传文件
  367. this.isUploadFileIng = true
  368. // 先创建文件记录
  369. putData('/test/file', { 'runnerId': this.modelParames.curPlanId, 'name': this.selectFileName, 'size': this.uploadSize }).then(res => {
  370. this.fid = res.id
  371. // /test/file/{id}/bytes
  372. // this.uploadFileUrl = window.STATIC_CONFIG.proxyUrl + '/test/file/' + fid + '/bytes' // 文件上传地址
  373. this.$refs.upload.submit()
  374. this.isUploadFileIng = false
  375. this.isSelectedFile = false
  376. }).catch(res => {
  377. this.isUploadFileIng = false
  378. this.isSelectedFile = false
  379. })
  380. },
  381. updateActionUrl() {
  382. return new Promise((r) => {
  383. this.$nextTick(() => {
  384. this.uploadFileUrl = '/test/file/' + this.fid + '/bytes' // 文件上传地址
  385. r()
  386. })
  387. })
  388. },
  389. updateActionUrl2(obj, id) {
  390. return new Promise((r) => {
  391. this.$nextTick(() => {
  392. this.uploadFileName = obj.name
  393. this.uploadFileUrl = '/test/file/' + id + '/bytes' // 文件上传地址
  394. r()
  395. })
  396. })
  397. },
  398. uploadSuccess() {
  399. this.$message({
  400. message: '文件上传成功',
  401. type: 'success',
  402. offset: window.screen.height / 3
  403. })
  404. this.getList()
  405. },
  406. async multDelete() {
  407. // 批量删除
  408. for (let i = 0; i < this.multipleSelection.length; i++) {
  409. const row = this.multipleSelection[i]
  410. let isOk = true
  411. await delRecord('/test/file/', row.id).then(res => {
  412. }).catch(res => {
  413. this.$message({
  414. message: res.message,
  415. type: 'error',
  416. offset: window.screen.height / 3
  417. })
  418. isOk = false
  419. })
  420. if (!isOk) {
  421. break
  422. }
  423. }
  424. this.getList()
  425. },
  426. deleteFile(row) {
  427. delRecord('/test/file/', row.id).then(res => {
  428. this.$message({
  429. message: '文件删除成功',
  430. type: 'success',
  431. offset: window.screen.height / 3
  432. })
  433. this.getList()
  434. }).catch(res => {
  435. this.$message({
  436. message: res.message,
  437. type: 'error',
  438. offset: window.screen.height / 3
  439. })
  440. })
  441. },
  442. downloadFile(row) {
  443. const url = `/test/file/${row.id}/bytes`
  444. httpGet(url).then(res => {
  445. console.log(res)
  446. }).catch(res => {
  447. })
  448. },
  449. readFile(row) {
  450. // 从设备上读取文件
  451. this.isReadFileId = row.id
  452. const url = `/equip/file/${this.modelParames.curPlanId}/get`
  453. postData(url, 'fileId=' + row.id).then(res => {
  454. this.$message({
  455. message: '文件' + row.name + '正在读取中,请等待读取完成',
  456. type: 'info',
  457. offset: window.screen.height / 3
  458. })
  459. const that = this
  460. setTimeout(() => {
  461. that.getList()
  462. }, 3000)
  463. }).catch(res => {
  464. this.isReadFileId = 0
  465. this.$message({
  466. message: res.message,
  467. type: 'error',
  468. offset: window.screen.height / 3
  469. })
  470. })
  471. },
  472. sendFile(row) {
  473. // 下发文件到设备
  474. this.isSendFileId = row.id
  475. const url = `/equip/file/${this.modelParames.curPlanId}/put`
  476. postData(url, 'fileId=' + row.id).then(res => {
  477. this.$message({
  478. message: '文件' + row.name + '正在下发中,请等待下发完成',
  479. type: 'info',
  480. offset: window.screen.height / 3
  481. })
  482. const that = this
  483. setTimeout(() => {
  484. that.getList()
  485. }, 3000)
  486. }).catch(res => {
  487. this.isSendFileId = 0
  488. this.$message({
  489. message: res.message,
  490. type: 'error',
  491. offset: window.screen.height / 3
  492. })
  493. })
  494. },
  495. // 表单取消按钮
  496. cancelForm() {
  497. if (this.isUploadFileIng) {
  498. this.$message({
  499. message: '文件正在下发中',
  500. type: 'info',
  501. offset: window.screen.height / 3
  502. })
  503. return
  504. }
  505. this.comonentVar.dialogVisible = false
  506. }
  507. }
  508. }
  509. </script>
  510. <style lang="scss">
  511. .sendFileName{
  512. float: left;
  513. overflow: hidden;
  514. text-overflow: ellipsis;
  515. width: 310px;
  516. white-space: nowrap;
  517. cursor: default;
  518. }
  519. .sendFileProcess {
  520. float: left;
  521. width: 300px;
  522. margin-top: 3px;
  523. background-color: #ccc;
  524. position: relative;
  525. border-radius: 5px;
  526. height: 10px;
  527. line-height: 10px;
  528. margin-left: 20px;
  529. .sendFileProcess2 {
  530. position: absolute;
  531. left: 0;
  532. top: 0;
  533. padding: 0;
  534. width: 0px;
  535. border-radius: 5px;
  536. height: 10px;
  537. line-height: 10px;
  538. background-color: blue;
  539. }
  540. }
  541. .sendFileProcessNumber{
  542. float: left;
  543. margin-left: 30px;
  544. font-weight: bold;
  545. }
  546. </style>