阅行客电子档案
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

364 lines
12 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. <template>
  2. <div class="upload-file">
  3. <!-- 上传附件curd -->
  4. <div v-if="isUploadDetail" class="upload-curd">
  5. <div class="upload-btn">
  6. <el-button icon="el-icon-plus" size="small" type="primary">添加</el-button>
  7. <input id="upFile" type="file" name="upFile" @change="changeFile($event)">
  8. </div>
  9. <el-button icon="el-icon-delete" :disabled="selections.length === 0" @click="toDelete(selections)">删除</el-button>
  10. <el-button icon="el-icon-sort" @click="showSort">排序</el-button>
  11. </div>
  12. <!--表格渲染-->
  13. <el-table
  14. ref="table"
  15. :data="tableData"
  16. style="min-width: 100%"
  17. height="calc(100vh - 382px)"
  18. @row-click="clickRowHandler"
  19. @selection-change="selectionChangeHandler"
  20. >
  21. <el-table-column v-if="isUploadDetail" type="selection" width="55" align="center" />
  22. <el-table-column type="index" label="序号" width="55" align="center" />
  23. <el-table-column prop="file_name" label="文件名称" show-overflow-tooltip min-width="140" />
  24. <el-table-column prop="file_type" label="格式" min-width="60" align="center" />
  25. <el-table-column prop="file_size" label="大小" min-width="85" align="center">
  26. <template slot-scope="scope">
  27. {{ (scope.row.file_size / 1024).toFixed(2) + 'kB' }}
  28. </template>
  29. </el-table-column>
  30. <el-table-column prop="file_dpi" label="分辨率" min-width="100" align="center">
  31. <template slot-scope="scope">
  32. <div v-if="!scope.row.file_dpi"> - </div>
  33. <div v-else> {{ scope.row.file_dpi }} </div>
  34. </template>
  35. </el-table-column>
  36. <el-table-column prop="file_thumbnail" label="缩览图" min-width="60" align="center">
  37. <template slot-scope="scope">
  38. <div v-if="scope.row.file_type === 'jpg' || scope.row.file_type === 'jpeg' || scope.row.file_type === 'png' || scope.row.file_type === 'bmp'|| scope.row.file_type === 'gif'">
  39. <i class="fileIcon icon-image" />
  40. </div>
  41. <div v-else-if="scope.row.file_type === 'xlsx' || scope.row.file_type === 'xls'">
  42. <i class="fileIcon icon-excel" />
  43. </div>
  44. <div v-else-if="scope.row.file_type === 'docx' || scope.row.file_type === 'doc'">
  45. <i class="fileIcon icon-word" />
  46. </div>
  47. <div v-else-if="scope.row.file_type === 'pdf'">
  48. <i class="fileIcon icon-pdf" />
  49. </div>
  50. <div v-else-if="scope.row.file_type === 'ppt' || scope.row.file_type === 'pptx'">
  51. <i class="fileIcon icon-ppt" />
  52. </div>
  53. <div v-else-if="scope.row.file_type === 'zip' || scope.row.file_type === 'rar'">
  54. <i class="fileIcon icon-zip" />
  55. </div>
  56. <div v-else-if="scope.row.file_type === 'txt'">
  57. <i class="fileIcon icon-txt" />
  58. </div>
  59. <div v-else>
  60. <i class="fileIcon icon-other" />
  61. </div>
  62. </template>
  63. </el-table-column>
  64. <el-table-column prop="create_time" label="创建时间" min-width="110" align="center" />
  65. <!-- && !recycleMain.isRecycle -->
  66. <el-table-column v-if="!isUploadDetail " label="操作" min-width="80" align="center">
  67. <template slot-scope="scope">
  68. <el-button class="file-down iconfont icon-weibiaoti-2" @click="downloadFile(scope.row)">下载</el-button>
  69. </template>
  70. </el-table-column>
  71. </el-table>
  72. <!-- 点击缩略图看大图 -->
  73. <el-dialog class="preview-dialog" :append-to-body="true" :close-on-click-modal="false" :before-close="handleClose" :visible="showCoverVisible" title="查看大图">
  74. <span class="dialog-right-top" />
  75. <span class="dialog-left-bottom" />
  76. <div class="setting-dialog" style="max-height:calc(100vh - 230px); overflow:auto;">
  77. <img style="max-width:100%; object-fit: contain;" :src="previewSrc" :onerror="defaultImg">
  78. </div>
  79. </el-dialog>
  80. <!-- 排序 -->
  81. <el-dialog :close-on-click-modal="false" :append-to-body="true" title="排序" :visible.sync="sortVisible" @opened="opened">
  82. <span class="dialog-right-top" />
  83. <span class="dialog-left-bottom" />
  84. <div class="setting-dialog">
  85. <i class="drag-tip">提示请通过拖动鼠标来调整当前顺序</i>
  86. <el-table :data="sortTableData" class="file-sort" style="width: 100%;max-height: 70vh;" row-key="id">
  87. <el-table-column type="index" label="序号" width="100" align="center" />
  88. <el-table-column prop="file_name" label="文件名称" />
  89. </el-table>
  90. <div slot="footer" class="dialog-footer">
  91. <el-button type="primary" @click.native="handleSort">保存</el-button>
  92. </div>
  93. </div>
  94. </el-dialog>
  95. <!-- 删除附件 -->
  96. <el-dialog title="删除附件" :append-to-body="true" :close-on-click-modal="false" :visible.sync="deleteVisible" :before-close="handleClose">
  97. <span class="dialog-right-top" />
  98. <span class="dialog-left-bottom" />
  99. <div class="setting-dialog">
  100. <div class="dialog-delt">
  101. <p><span>确定删除已选择的附件吗</span></p>
  102. </div>
  103. <div slot="footer" class="dialog-footer">
  104. <el-button type="primary" @click.native="handleDeltConfirm">确定</el-button>
  105. </div>
  106. </div>
  107. </el-dialog>
  108. </div>
  109. </template>
  110. <script>
  111. import { FetchInitArchiveFilesView, FetchEditFile, FetchDeleteFile, FetchFileSort } from '@/api/archivesManage/archivesList'
  112. import { archivesUpload } from '@/utils/upload'
  113. import { downloadFile, getCurrentTime } from '@/utils/index'
  114. import { mapGetters } from 'vuex'
  115. import { form } from '@crud/crud'
  116. import Sortable from 'sortablejs'
  117. export default {
  118. name: 'UploadFile',
  119. components: {},
  120. mixins: [
  121. form({})
  122. ],
  123. // inject: ['recycleMain'],
  124. props: {
  125. isUploadDetail: {
  126. type: Boolean,
  127. default: true
  128. },
  129. categoryId: {
  130. type: String,
  131. default: function() {
  132. return ''
  133. }
  134. },
  135. arcId: {
  136. type: String,
  137. default: function() {
  138. return ''
  139. }
  140. }
  141. },
  142. data() {
  143. return {
  144. defaultImg: 'this.src="' + require('@/assets/images/cover-bg.png') + '"',
  145. tableData: [], // 附件list
  146. selections: [], // table - 选中的
  147. showCoverVisible: false, // 查看大图dialog
  148. sortTableData: [], // 排序data
  149. sortVisible: false, // 排序dialog
  150. deleteVisible: false, // 删除附件 dialog
  151. deleteData: [], // 删除选中的data
  152. file: null, // 附件 change
  153. fileNames: '', // 附件 - name
  154. formatType: '', // 附件 - type
  155. postfix: '', // 附件 - 文件后缀
  156. fileSize: '', // 附件 - 大小
  157. filePath: '', // 附件 - path
  158. px: '', // 附件 - 分辨率
  159. nowDate: '', // 当前时间
  160. previewSrc: '' // 查看大图src
  161. }
  162. },
  163. computed: {
  164. ...mapGetters([
  165. 'baseApi'
  166. ])
  167. },
  168. watch: {
  169. arcId: function(newValue, oldValue) {
  170. }
  171. },
  172. methods: {
  173. // 选择附件
  174. async changeFile(e) {
  175. this.file = e.target.files[0]
  176. this.fileSize = this.file.size
  177. this.formatType = this.file.type.substring(0, this.file.type.indexOf('/'))
  178. this.fileNames = this.file.name
  179. this.postfix = this.file.name.substring(
  180. this.fileNames.lastIndexOf('.') + 1,
  181. this.fileNames.length
  182. )
  183. if (this.formatType === 'image') {
  184. const fileBase64 = await this.getBase64(this.file)
  185. const res = await this.getImgPx(fileBase64)
  186. this.px = res.width + 'px*' + res.height + 'px'
  187. } else {
  188. this.px = ''
  189. }
  190. // 上传附件
  191. archivesUpload(this.baseApi + '/api/archives/uploadFile', this.file, this.categoryId).then(res => {
  192. if (res.data.code === 200) {
  193. this.filePath = res.data.data
  194. this.uploadSave()
  195. }
  196. })
  197. },
  198. // 上传附件 - 选择上传即保存
  199. uploadSave() {
  200. this.nowDate = getCurrentTime()
  201. const json = {
  202. 'file_name': this.fileNames,
  203. 'file_size': this.fileSize,
  204. 'file_type': this.postfix,
  205. 'file_path': this.filePath,
  206. 'sequence': null,
  207. 'archive_id': this.arcId,
  208. 'file_dpi': this.px,
  209. 'file_thumbnail': '',
  210. 'create_time': this.nowDate,
  211. 'id': null
  212. }
  213. const arrayUpload = []
  214. arrayUpload.push(json)
  215. const params = {
  216. 'categoryId': this.categoryId,
  217. 'jsonString': JSON.stringify(arrayUpload)
  218. }
  219. FetchEditFile(params).then(data => {
  220. this.$message.success('上传附件成功!')
  221. this.crud.refresh()
  222. this.getFileList()
  223. })
  224. },
  225. // 将上传的图片转为base64
  226. getBase64(file) {
  227. const reader = new FileReader()
  228. reader.readAsDataURL(file)
  229. return new Promise((resolve) => {
  230. reader.onload = () => {
  231. resolve(reader.result)
  232. }
  233. })
  234. },
  235. // 获取图片的分辨率
  236. getImgPx(img) {
  237. const image = new Image()
  238. image.src = img
  239. return new Promise((resolve) => {
  240. image.onload = () => {
  241. const width = image.width
  242. const height = image.height
  243. resolve({ width, height })
  244. }
  245. })
  246. },
  247. // 上传list
  248. getFileList() {
  249. const params = {
  250. 'categoryId': this.categoryId,
  251. 'archiveId': this.arcId
  252. }
  253. FetchInitArchiveFilesView(params).then(data => {
  254. this.tableData = data.returnlist
  255. })
  256. },
  257. // 下载附件
  258. downloadFile(row) {
  259. const url = this.baseApi + '/downloadFile' + row.file_path
  260. fetch(url).then(res => res.blob()).then(blob => {
  261. downloadFile(blob, row.file_name.split('.')[0], row.file_type)
  262. }).catch(() => {
  263. this.$message.error('下载文件失败!')
  264. })
  265. },
  266. // 选择删除
  267. toDelete(data) {
  268. this.deleteData = data
  269. this.deleteVisible = true
  270. },
  271. // 确认删除
  272. handleDeltConfirm() {
  273. this.deleteVisible = false
  274. const ids = []
  275. this.deleteData.forEach(val => {
  276. ids.push(val.id)
  277. })
  278. const params = {
  279. 'ids': ids,
  280. 'categoryId': this.categoryId
  281. }
  282. // 删除fetch
  283. FetchDeleteFile(params).then(res => {
  284. this.crud.delAllLoading = false
  285. this.$message.success('删除成功!')
  286. this.crud.refresh()
  287. this.getFileList()
  288. })
  289. },
  290. // 排序 - 行拖拽
  291. rowDrop(className, targetName) {
  292. // 此时找到的元素是要拖拽元素的父容器
  293. const tbody = document.querySelector('.' + className + ' .el-table__body-wrapper tbody')
  294. const that = this
  295. Sortable.create(tbody, {
  296. // 指定父元素下可被拖拽的子元素
  297. draggable: '.el-table__row',
  298. onEnd({ newIndex, oldIndex }) {
  299. if (newIndex === oldIndex) return
  300. that[targetName].splice(newIndex, 0, that[targetName].splice(oldIndex, 1)[0])
  301. }
  302. })
  303. },
  304. // 排序
  305. opened() {
  306. this.rowDrop('file-sort', 'sortTableData')
  307. },
  308. showSort() {
  309. this.sortVisible = true
  310. this.sortTableData = JSON.parse(JSON.stringify(this.tableData))
  311. },
  312. // 排序 - 保存
  313. handleSort() {
  314. const ids = []
  315. const sequences = []
  316. this.sortTableData.map((value, index) => {
  317. ids.push(value.id)
  318. sequences.push(index + 1)
  319. })
  320. const params = {
  321. 'categoryId': this.categoryId,
  322. 'ids': ids,
  323. 'sequences': sequences
  324. }
  325. FetchFileSort(params).then((res) => {
  326. this.sortVisible = false
  327. this.$message.success('附件排序成功!')
  328. this.crud.refresh()
  329. this.getFileList()
  330. })
  331. },
  332. // table
  333. clickRowHandler(row) {
  334. this.$refs.table.toggleRowSelection(row)
  335. },
  336. // table
  337. selectionChangeHandler(val) {
  338. this.selections = val
  339. },
  340. // dialog - close
  341. handleClose(done) {
  342. this.showCoverVisible = false
  343. done()
  344. },
  345. // 查看大图
  346. showCoverPreview(row) {
  347. this.showCoverVisible = true
  348. this.previewSrc = this.baseApi + '/downloadFile' + row.file_path
  349. }
  350. }
  351. }
  352. </script>
  353. <style lang="scss" scoped>
  354. .svg-style{
  355. width: 60px;
  356. height: 32px;
  357. }
  358. </style>