material_file.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. 'use strict';
  2. /**
  3. * 材料调差 - 附件
  4. * @author LanJianRong
  5. * @date 2020/06/30
  6. * @version
  7. */
  8. $(document).ready(function () {
  9. // 每页最多几个附件
  10. const pageCount = 20;
  11. // 全局fileData初始化
  12. let fileData = fileList || []
  13. // let currPageFileData = [];
  14. handleFileList(fileData)
  15. getAllList()
  16. $('#upload-file-ok').click(function () {
  17. const files = Array.from($('#upload-fujian-file')[0].files)
  18. const valiData = files.map(v => {
  19. const ext = v.name.substring(v.name.lastIndexOf('.') + 1)
  20. return {
  21. size: v.size,
  22. ext
  23. }
  24. })
  25. if (validateFiles(valiData)) {
  26. if (files.length) {
  27. const formData = new FormData()
  28. files.forEach(file => {
  29. formData.append('name', file.name)
  30. formData.append('size', file.size)
  31. formData.append('file', file)
  32. })
  33. postDataWithFile(window.location.pathname + '/upload', formData, function (result) {
  34. $('#upload-fujian-file').val('');
  35. handleFileList(result)
  36. $('#addfujian').modal('hide');
  37. if (!$('#file-list tr').length) {
  38. getAllList();
  39. } else {
  40. const curPageNo = $('#file-pagination > li[class="page-item active"] > a').text() || 1
  41. getAllList(parseInt(curPageNo));
  42. }
  43. });
  44. }
  45. }
  46. })
  47. // 选择/未选所有期列表
  48. // $('#file-checkbox').click(function() {
  49. // getAllList()
  50. // })
  51. // 删除附件
  52. $('body').on('click', '.delete-file', function () {
  53. let attid = $(this).data('attid');
  54. const data = {id: attid};
  55. postData(window.location.pathname + '/delete', data, function () {
  56. const idx = fileData.findIndex(file => file.id === parseInt(attid))
  57. idx !== -1 && fileData.splice(idx, 1)
  58. const curPageNo = parseInt($('#file-pagination > li[class="page-item active"] > a').text()) || 1
  59. if ($('#file-list tr').length === 1) {
  60. getAllList(curPageNo - 1);
  61. } else {
  62. getAllList(curPageNo);
  63. }
  64. // self.parents('tr').remove();
  65. // // 重新排序
  66. // let newsort = 1;
  67. // $('#file-list tr').each(function(){
  68. // $(this).children('td').eq(0).text(newsort);
  69. // newsort++;
  70. // });
  71. });
  72. });
  73. // 切换页数
  74. $('#file-pagination').on('click', '.page-item a', function () {
  75. // 找到当前的pageNo
  76. const curPageNo = $('#file-pagination > li[class="page-item active"] > a').text() || 1
  77. const btnType = $(this).attr('aria-label')
  78. const total = calcCount();
  79. // btnType存在,说明点击的是前一个/后一个
  80. // btnType不存在,点击的是页数
  81. if (btnType) {
  82. if (btnType === 'Previous') {
  83. // 只有大于1时才处理
  84. if (parseInt(curPageNo) !== 1) {
  85. getAllList(curPageNo - 1)
  86. }
  87. } else if(btnType === 'Next') {
  88. if (parseInt(curPageNo) !== Math.ceil(total/pageCount)) {
  89. getAllList(parseInt(curPageNo) + 1)
  90. }
  91. } else if(btnType === 'Start') {
  92. getAllList(1)
  93. } else {
  94. getAllList(Math.ceil(total/pageCount))
  95. }
  96. } else {
  97. curPageNo !== $(this).text() && getAllList(parseInt($(this).text()))
  98. }
  99. });
  100. $('.dropdown-item').click(function() {
  101. const type = $('#dropdownMenuButton').attr('btn-type')
  102. if (type === 'curr') {
  103. $(this).text('当前期')
  104. $('#dropdownMenuButton').text('所有期')
  105. $('#dropdownMenuButton').attr('btn-type', 'all')
  106. } else {
  107. $(this).text('所有期')
  108. $('#dropdownMenuButton').text('当前期')
  109. $('#dropdownMenuButton').attr('btn-type', 'curr')
  110. }
  111. getAllList()
  112. })
  113. // 生成所有附件列表
  114. function getAllList(currPageNum = 1) {
  115. const isCheckAll = $('#dropdownMenuButton').attr('btn-type') === 'all'
  116. // 未选中checkbox,需要过滤出来当前期的数据
  117. const filterFileData = fileData && isCheckAll ? fileData : fileData.filter(file => file.mid === parseInt(mid) && file.tid === parseInt(tid))
  118. const total = calcCount();
  119. // 总页数
  120. const pageNum = Math.ceil(total/pageCount);
  121. // 当前页附件内容
  122. const currPageAttData = fileData && isCheckAll ? fileData.map((v, index) => {
  123. return {...v, index }
  124. }).slice((currPageNum-1)*pageCount, currPageNum*pageCount)
  125. : filterFileData.map((v, index) => {
  126. return {...v, index }
  127. }).slice((currPageNum-1)*pageCount, currPageNum*pageCount);
  128. currPageFileData = currPageAttData;
  129. renderHtml(currPageAttData);
  130. // 渲染分页器
  131. renderPagination(currPageNum, pageNum)
  132. };
  133. function renderPagination(pageNo, pageSize) {
  134. $('#file-pagination').empty()
  135. if (pageSize < 2) return
  136. const btnHtml = `
  137. <li class="page-item page-begin">
  138. <a class="page-link" href="#" aria-label="Start">
  139. <span aria-hidden="true">&laquo;</span>
  140. </a>
  141. </li>
  142. <li class="page-item page-back">
  143. <a class="page-link" href="#" aria-label="Previous">
  144. <span aria-hidden="true">&lsaquo;</span>
  145. </a>
  146. </li>
  147. <li class="page-item page-next">
  148. <a class="page-link" href="#" aria-label="Next">
  149. <span aria-hidden="true">&rsaquo;</span>
  150. </a>
  151. </li>
  152. <li class="page-item page-end">
  153. <a class="page-link" href="#" aria-label="End">
  154. <span aria-hidden="true">&raquo;</span>
  155. </a>
  156. </li>`
  157. $('#file-pagination').append(btnHtml)
  158. let html = ''
  159. // 考虑极端情况
  160. if (pageNo - 2 <= 0 || pageNo + 2 >= pageSize) {
  161. if (pageNo < 3) {
  162. const max = pageSize > 5 ? 5 : pageSize
  163. for (let i = 0; i < max; i++) {
  164. html += pageNo === i + 1 ?
  165. `<li class="page-item active"><a class="page-link" href="#">${i+1}</a></li>` :
  166. `<li class="page-item"><a class="page-link" href="#">${i+1}</a></li>`
  167. }
  168. } else {
  169. for (let i = (pageSize-4 > 0 ? pageSize-4 : 1 ); i <= pageSize; i++) {
  170. html += pageNo === i ?
  171. `<li class="page-item active"><a class="page-link" href="#">${i}</a></li>` :
  172. `<li class="page-item"><a class="page-link" href="#">${i}</a></li>`
  173. }
  174. }
  175. } else {
  176. for (let i = 0; i < pageSize; i++) {
  177. if (i + 1 === pageNo) {
  178. // 当前
  179. html+=`<li class="page-item active"><a class="page-link" href="#">${i + 1}</a></li>`
  180. } else if(i + 2 === pageNo && i + 2 <= pageSize) {
  181. // 后一页
  182. html+=`<li class="page-item"><a class="page-link" href="#">${i + 1}</a></li>`
  183. } else if (i + 3 === pageNo && i + 3 <= pageSize) {
  184. // 后两页
  185. html+=`<li class="page-item"><a class="page-link" href="#">${i + 1}</a></li>`
  186. } else if(i === pageNo) {
  187. // 前一页
  188. html+=`<li class="page-item"><a class="page-link" href="#">${i + 1}</a></li>`
  189. } else if (i -1 === pageNo && i -1 >= 0) {
  190. // 前两页
  191. html+=`<li class="page-item"><a class="page-link" href="#">${i + 1}</a></li>`
  192. }
  193. }
  194. }
  195. $('.page-next').before(html)
  196. };
  197. function renderHtml(list) {
  198. let html = '';
  199. $('#check-all-file').prop("checked", false)
  200. list.forEach(fileInfo => {
  201. html += `<tr style="height: 31px;">
  202. <td width="25"><input type="checkbox" class="check-file" file-id=${fileInfo.id}></td>
  203. <td>${fileInfo.index + 1}</td>
  204. <td><a href="${fileInfo.filepath}" target="_blank">${fileInfo.file_name}</a></td>
  205. <td>${fileInfo.file_size}</td>
  206. <td>第${fileInfo.s_order}期</td>
  207. <td>${fileInfo.upload_time}</td>`
  208. if (fileInfo.showDel ) {
  209. html += `<td>
  210. <a href="file/${fileInfo.id}/download" class="btn btn-light btn-sm" title="下载"><span class="fa fa-download text-primary"></span></a>
  211. <a href="javascript:void(0);" class="btn btn-light btn-sm delete-file" data-attid="${fileInfo.id}" title="删除附件">
  212. <span class="fa fa-trash text-danger"></span>
  213. </a>
  214. </td></tr>`
  215. } else {
  216. html += `<td><a href="${fileInfo.filepath}" class="btn btn-light btn-sm" title="下载"><span class="fa fa-download text-primary"></span></a></td></tr>`
  217. }
  218. })
  219. $('#file-list').empty();
  220. $('#file-list').append(html);
  221. };
  222. $('#file-list').on('click', '.check-file', function() {
  223. const checkedList = $('#file-list').find('input:checked')
  224. const childs = $('#file-list').children().length
  225. const checkBox = $('#check-all-file')
  226. if (checkedList.length === childs) {
  227. checkBox.prop("checked", true)
  228. } else {
  229. checkBox.prop("checked", false)
  230. }
  231. })
  232. $('#check-all-file').click(function() {
  233. const isCheck = $(this).is(':checked')
  234. $('#file-list').children().each(function() {
  235. $(this).find('input:checkbox').prop("checked", isCheck)
  236. })
  237. });
  238. $('#bach-download').click(async function() {
  239. const fileIds = []
  240. $( '#file-list .check-file:checked').each(function() {
  241. const fileId = $(this).attr('file-id')
  242. fileId && fileIds.push(fileId)
  243. })
  244. // console.log('fileIds', fileIds)
  245. if (fileIds.length) {
  246. if (fileIds.length > 20) {
  247. return toastr.warning(`最大允许20个文件(当前${fileIds.length}个)`)
  248. }
  249. toastr.success('正在进行下载并压缩文件...', '', { timeOut: 0, extendedTimeOut: 0})
  250. $(this).attr('disabled', "true");
  251. const btn = $(this);
  252. const fileArr = [];
  253. for (const id of fileIds) {
  254. const fileInfo = _.find(currPageFileData, { id: parseInt(id) });
  255. fileArr.push({
  256. url: fileInfo.orginpath, //文件的oss存储路径 (必填)
  257. name: fileInfo.file_name.substring(0, fileInfo.file_name.lastIndexOf(".")), // 文件名 (可选, 不需要填扩展名)
  258. foldPath: '' // (可选, 文件在压缩包中的存储路径)
  259. });
  260. }
  261. const packageName = `${tender.name}-材料调差-第${order}期-附件.zip`;
  262. try {
  263. zipOss.downloadFromAliOss(fileArr, packageName, btn);
  264. } catch (e) {
  265. btn.removeAttr('disabled');
  266. toastr.clear();
  267. toastr.error('批量下载失败');
  268. }
  269. // postCompressFile(`/tender/${tid}/measure/material/${order}/file/download/compresse-file`, {fileIds}, function(result) {
  270. // toastr.clear()
  271. // toastr.success('压缩文件成功')
  272. // btn.removeAttr('disabled')
  273. // const href = window.URL.createObjectURL(result)
  274. // $('#zipDown').attr('href', href);
  275. // $('#zipDown').attr('download', `${tender.name}-材料调差-第${order}期-附件.zip`);
  276. // $("#zipDown")[0].click();
  277. // }, () => {
  278. // btn.removeAttr('disabled')
  279. // toastr.clear()
  280. // toastr.error('批量下载失败')
  281. // });
  282. // postData( `/tender/${tid}/measure/material/${order}/file/download/compresse-file`, { fileIds })
  283. // $('#downloadZip').attr('href', `/tender/${tid}/measure/material/${order}/file/download/compresse-file?fileIds=${JSON.stringify(fileIds)}`);
  284. // $('#downloadZip')[0].click();
  285. }
  286. });
  287. function handleFileList(fileList) {
  288. fileData = fileList.map((file, index) => {
  289. let showDel = false
  290. // 只判断当前期,因为以往期都是只读的
  291. if (file.mid === parseInt(mid) && file.tid === parseInt(tid) && file.user_id === parseInt(cur_uid)) {
  292. if (materialStatus === auditConst.status.checked) {
  293. showDel = Boolean(file.extra_upload )
  294. } else {
  295. showDel = true
  296. }
  297. // if (!curAuditor) {
  298. // materialStatus === auditConst.status.uncheck && parseInt(cur_uid) === materialUid && (showDel = true)
  299. // materialStatus === auditConst.status.checkNo && parseInt(cur_uid) === materialUid && (showDel = true)
  300. // } else {
  301. // curAuditor.aid === parseInt(cur_uid) && (showDel = true)
  302. // }
  303. }
  304. return {...file, index, showDel}
  305. })
  306. };
  307. function calcCount() {
  308. // 附件总数
  309. let total = fileData && fileData.length;
  310. if($('#dropdownMenuButton').attr('btn-type') === 'curr') {
  311. total = fileData && fileData.filter(file => file.mid === parseInt(mid) && file.tid === parseInt(tid)).length
  312. }
  313. return total
  314. };
  315. $.subMenu({
  316. menu: '#sub-menu', miniMenu: '#sub-mini-menu', miniMenuList: '#mini-menu-list',
  317. toMenu: '#to-menu', toMiniMenu: '#to-mini-menu',
  318. key: 'menu.1.0.0',
  319. miniHint: '#sub-mini-hint', hintKey: 'menu.hint.1.0.1',
  320. callback: function (info) {
  321. if (info.mini) {
  322. $('.panel-title').addClass('fluid');
  323. $('#sub-menu').removeClass('panel-sidebar');
  324. } else {
  325. $('.panel-title').removeClass('fluid');
  326. $('#sub-menu').addClass('panel-sidebar');
  327. }
  328. autoFlashHeight();
  329. }
  330. });
  331. });
  332. /**
  333. * 校验文件大小、格式
  334. * @param {Array} files 文件数组
  335. */
  336. function validateFiles(files) {
  337. if (files.length > 10) {
  338. toastr.error('至多同时上传10个文件');
  339. return false
  340. }
  341. return files.every(file => {
  342. if (file.size > 1024 * 1024 * 30) {
  343. toastr.error('文件大小限制为30MB');
  344. return false
  345. }
  346. if (whiteList.indexOf('.' + file.ext) === -1) {
  347. toastr.error('请上传正确的格式文件');
  348. return false
  349. }
  350. return true
  351. })
  352. };