budget_info.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. const task_modal_template = `
  2. <div class="modal fade" id="modal" tabindex="-1" aria-hidden="true">
  3. <div class="modal-dialog modal-dialog-centered">
  4. <div class="modal-content rounded">
  5. <div class="modal-header">
  6. <h3 class="modal-title"><span class="prefix"></span>任务</h3>
  7. <div class="btn btn-sm btn-icon btn-active-color-primary" data-bs-dismiss="modal">
  8. <i class="ki-duotone ki-cross fs-1">
  9. <span class="path1"></span>
  10. <span class="path2"></span>
  11. </i>
  12. </div>
  13. </div>
  14. <div class="modal-body">
  15. <form>
  16. <div class="form-group">
  17. <!-- <input type="hidden" name="budget_id" value="">-->
  18. <input type="hidden" name="project_id" value="">
  19. <input type="hidden" name="item_id" value="">
  20. <input type="hidden" name="item_code" value="">
  21. <input type="hidden" name="task_id" value="">
  22. <div class="fv-row form-group mb-3">
  23. <label for="task_name" class="form-label required">任务名称</label>
  24. <input type="text" class="form-control" name="task_name" id="task_name" placeholder="请输入任务名称" required />
  25. </div>
  26. <div class="fv-row form-group mb-3">
  27. <label for="budget_id" class="form-label">概算单元</label>
  28. <select class="form-select" name="budget_id" id="budget_id"></select>
  29. </div>
  30. <div class="fv-row form-group mb-3">
  31. <label for="task_sort" class="form-label">任务排序</label>
  32. <input type="number" class="form-control" name="task_sort" id="task_sort" placeholder="请输入任务排序"/>
  33. </div>
  34. <div class="fv-row form-group mb-3">
  35. <label for="task_desc" class="form-label">任务描述</label>
  36. <textarea type="number" class="form-control" name="task_desc" id="task_desc" placeholder="请输入任务描述"></textarea>
  37. </div>
  38. <!-- <div class="form-check mb-3" id="delete_file_box">-->
  39. <!-- <input class="form-check-input" type="checkbox" value="" id="delete_file" name="delete_file"/>-->
  40. <!-- <label class="form-check-label ms-5 text-primary " for="delete_file">-->
  41. <!-- 删除原数据文件-->
  42. <!-- </label>-->
  43. <!-- </div>-->
  44. <div class="fv-row">
  45. <div id="file_upload_dropzone">
  46. <div class="dropzone">
  47. <div class="dz-message dropzone-select">
  48. <i class="ki-duotone ki-file-up fs-3x text-primary"><span class="path1"></span><span class="path2"></span></i>
  49. <div class="ms-4">
  50. <h3 class="fs-5 fw-bold text-gray-900 mb-1">将文件拖放到此处或单击上传。</h3>
  51. <span class="fs-7 fw-semibold text-gray-500">最多可上传 5 个文件,文件最大10M</span>
  52. </div>
  53. </div>
  54. </div>
  55. <div class="dropzone dropzone-queue">
  56. <div class="dropzone-items wm-200px">
  57. <div class="dropzone-item" style="display:none">
  58. <div class="dropzone-file">
  59. <div class="dropzone-filename" title="some_image_file_name.jpg">
  60. <span data-dz-name>some_image_file_name.jpg</span>
  61. <strong>(<span data-dz-size>340kb</span>)</strong>
  62. </div>
  63. <div class="dropzone-error" data-dz-errormessage></div>
  64. </div>
  65. <div class="dropzone-toolbar">
  66. <span class="dropzone-delete" data-dz-remove><i class="bi bi-x fs-1"></i></span>
  67. </div>
  68. </div>
  69. </div>
  70. </div>
  71. </div>
  72. </div>
  73. </div>
  74. </form>
  75. </div>
  76. <div class="modal-footer">
  77. <button type="button" class="btn btn-light" data-bs-dismiss="modal">取消</button>
  78. <button type="button" class="btn btn-light-success" onclick="SaveProject(true)">提交</button>
  79. <button type="button" class="btn btn-primary" onclick="SaveProject()">保存草稿</button>
  80. </div>
  81. </div>
  82. </div>
  83. </div>`
  84. $('.app-main .app-container').append(task_modal_template)
  85. const table_add_task_btn_template = `<button type="button" class="task_add_btn btn btn-primary btn-sm" onclick="Add('{0}')">添加任务</button>`
  86. const table = '#table',
  87. $modal = $('#modal')
  88. $modal.find('#budget_id').html($('#budget_id_options').html())
  89. $(function () {
  90. InitFileUpload()
  91. })
  92. let _fileUploadDropzone = null;
  93. function InitFileUpload() {
  94. const id = "#modal";
  95. const dropzone = document.querySelector(id);
  96. // set the preview element template
  97. const previewNode = dropzone.querySelector(".dropzone-item");
  98. previewNode.id = "";
  99. const previewTemplate = previewNode.parentNode.innerHTML;
  100. previewNode.parentNode.removeChild(previewNode);
  101. _fileUploadDropzone = new Dropzone(id, {
  102. url: "/",
  103. parallelUploads: 10,
  104. previewTemplate: previewTemplate,
  105. autoProcessQueue: false, //关闭自动上传功能
  106. maxFiles: 5,
  107. maxFilesize: 10, // MB
  108. previewsContainer: id + " .dropzone-items", //
  109. clickable: id + " .dropzone-select", //
  110. acceptedFiles: '.csv,.xls,.xlsx',
  111. accept: function (file, done) {
  112. console.log('DONE', file, done)
  113. if (file.type.includes('csv') || file.type.includes('.xls') || file.type.includes('sheet')) {
  114. done()
  115. } else {
  116. done('文件类型非法,只允许.csv,.xls,.xlsx文件')
  117. }
  118. },
  119. dictInvalidFileType: '文件类型非法,只允许.csv,.xls,.xlsx文件',
  120. // dictRemoveFileConfirmation: '确定移除文件吗?',
  121. dictFileTooBig: '文件[{{filesize}}M]过大,最大允许{{maxFilesize}}M。',
  122. dictMaxFilesExceeded: '最多只能上传5个,每个文件不超过10M',
  123. });
  124. _fileUploadDropzone.on("addedfile", function (file) {
  125. const dropzoneItems = dropzone.querySelectorAll('.dropzone-item');
  126. dropzoneItems.forEach(dropzoneItem => {
  127. dropzoneItem.style.display = '';
  128. });
  129. if (_fileUploadDropzone.getAcceptedFiles().findIndex(item => item.name === file.name) >= 0) {
  130. MsgWarning('文件已存在')
  131. _fileUploadDropzone.removeFile(file);
  132. }
  133. });
  134. // _fileUploadDropzone.on("removedfile", function (file) {
  135. // _files = _files.filter(item=>item.name!==file.name)
  136. // console.log('removedfile', file,_files)
  137. // })
  138. }
  139. function RenderRightBox_Custom(data) {
  140. $quotaBox.data("table-url", `/api/quota/list`)
  141. $('.table_radio_box .form-check').hide()
  142. $rightBoxHeader.find('[name="table_radio"]').prop("disabled", false).off('change.iwb')
  143. $rightBoxHeader.find('[name="table_radio"]').on('change.iwb', function () {
  144. const val = $(this).val()
  145. if (val === 'quota') {
  146. $taskBox.hide()
  147. QuotaNavTab(data)
  148. } else {
  149. _taskTable(data)
  150. }
  151. })
  152. if (data.children_count > 0 || data.chapter) {
  153. _renderTask(data)
  154. } else {
  155. $rightBoxHeader.find('.badge').text('定额输入明细').removeClass('badge-primary').addClass('badge-success')
  156. $rightBoxHeader.find('#task_radio').prop("disabled", true)
  157. $rightBoxHeader.find('#quota_radio').prop("checked", true)
  158. QuotaNavTab(data)
  159. }
  160. function _renderTask(data) {
  161. $rightBoxHeader.find('.badge').text('任务列表').removeClass('badge-success').addClass('badge-primary')
  162. $rightBoxHeader.find('#task_radio').prop("checked", true)
  163. const budget_id = 0
  164. $taskBox.html(table_template.format(budget_id, table_add_task_btn_template.format(budget_id), table_run_select_template))
  165. _taskTable(data)
  166. }
  167. function _taskTable(data) {
  168. $quotaBox.hide()
  169. const $table = $taskBox.find('.table')
  170. IwbTable($table, {
  171. url: `/api/task/list/${project_id}/${data.item_code}`,
  172. columns: [
  173. {
  174. title: '任务编号',
  175. data: 'id',
  176. width: '100px',
  177. },
  178. {
  179. title: '任务名称',
  180. data: 'task_name',
  181. width: '240px',
  182. },
  183. {
  184. title: '任务排序',
  185. data: 'task_sort',
  186. width: '100px',
  187. },
  188. {
  189. title: '概算单元',
  190. data: 'budget_id',
  191. width: '130px',
  192. render: (row) => {
  193. const budget_name = $modal.find(`[name="budget_id"] option[value='${row.budget_id}']`)
  194. return budget_name.length ? budget_name.text() : '-'
  195. }
  196. },
  197. {
  198. title: '文件数据',
  199. data: 'file_data',
  200. width: 'auto',
  201. render: (row) => {
  202. let str = ``
  203. const file_paths = row.file_path ? row.file_path.split(',') : []
  204. if (file_paths.length) {
  205. for (let i = 0; i < file_paths.length; i++) {
  206. const path = file_paths[i] || ""
  207. if (!path) continue
  208. const names = path.split('/')
  209. const file_name = names[names.length - 1]
  210. str += `<a href="#" onclick="DownloadFile('/api/task/download?filename=${encodeURIComponent(path)}','${file_name}')" class="link link-info px-2">${file_name}</a>`
  211. }
  212. } else {
  213. str = "-"
  214. }
  215. return str
  216. }
  217. },
  218. {
  219. title: '任务状态',
  220. data: 'task_status',
  221. width: '180px',
  222. render: (row) => {
  223. let str = ``
  224. if (row.process_status === 0) {
  225. str += `<span class="badge badge-secondary">草稿</span>`
  226. } else if (row.process_status === 1) {
  227. str += `<span class="badge badge-light-primary">等待运行</span>`
  228. } else if (row.process_status === 2) {
  229. str += `<span class="badge badge-light-info">运行中</span>`
  230. // if (row.send_status === 0) {
  231. // str += `<span class="badge badge-light-primary ms-3">未发送</span>`
  232. // } else if (row.send_status === 1){
  233. // str += `<span class="badge badge-light-warning ms-3">发送中</span>`
  234. // } else if (row.send_status === 2){
  235. // str += `<span class="badge badge-light-success ms-3">发送完成</span>`
  236. // } else if (row.send_status === 3){
  237. // str += `<span class="badge badge-light-danger ms-3">发送失败</span>`
  238. // }
  239. // if (row.process_status === 0) {
  240. // str += `<span class="badge badge-light-primary ms-3">未处理</span>`
  241. // } else if (row.process_status === 1){
  242. // str += `<span class="badge badge-light-warning ms-3">处理中</span>`
  243. // } else if (row.process_status === 2){
  244. // str += `<span class="badge badge-light-success ms-3">处理完成</span>`
  245. //
  246. // } else if (row.process_status === 3){
  247. // str += `<span class="badge badge-light-danger ms-3">处理失败</span>`
  248. // }
  249. } else if (row.process_status === 200) {
  250. str += `<span class="badge badge-light-success">运行成功</span>`
  251. } else if (row.process_status === 4) {
  252. str += `<span class="badge badge-light-danger" data-bs-toggle="tooltip" data-bs-placement="top" title="${row.process_error}">运行失败</span>`
  253. } else if (row.process_status === 5) {
  254. str += `<span class="badge badge-warning">取消运行</span>`
  255. }
  256. return str
  257. }
  258. },
  259. {
  260. title: '操作',
  261. data: 'id',
  262. width: '160px',
  263. render: (row) => {
  264. let str = ``
  265. if (row.process_status === 0) {
  266. str += `<button type="button" class="btn btn-icon btn-sm btn-light-primary" data-bs-toggle="tooltip" data-bs-placement="top" title="开始任务" onclick="StarTask(${row.id})"><i class="ki-duotone ki-add-notepad fs-1"><span class="path1"></span><span class="path2"></span><span class="path3"></span><span class="path4"></span></i></button>`
  267. } else if (row.process_status === 1 || row.process_status === 2) {
  268. str += `<button type="button" class="btn btn-icon btn-sm btn-light-danger" data-bs-toggle="tooltip" data-bs-placement="top" title="取消任务" onclick="CancelTask(${row.id})"><i class="ki-duotone ki-cross-square fs-1"><span class="path1"></span><span class="path2"></span></i></button>`
  269. } else if (row.process_status === 200) {
  270. // str += `<button type="button" class="btn btn-icon btn-sm btn-light-warning" data-bs-toggle="tooltip" data-bs-placement="top" title="重新运行" onclick="ReStarTask(${row.id})"><i class="ki-duotone ki-add-notepad fs-1"><span class="path1"></span><span class="path2"></span><span class="path3"></span><span class="path4"></span></i></button>`
  271. // if (row.process_status === 0) {
  272. // str += `<button type="button" class="btn btn-icon btn-sm btn-light-primary" data-bs-toggle="tooltip" data-bs-placement="top" title="开始处理" onclick="StartProcessTask(${row.id})"><i class="ki-duotone ki-book-square fs-1"><span class="path1"></span><span class="path2"></span><span class="path3"></span></i></button>`
  273. // } else if (row.process_status === 2) {
  274. // str += `<button type="button" class="btn btn-icon btn-sm btn-light-warning" data-bs-toggle="tooltip" data-bs-placement="top" title="重新处理" onclick="ReStartProcessTask(${row.id})"><i class="ki-duotone ki-book-square fs-1"><span class="path1"></span><span class="path2"></span><span class="path3"></span></i></button>`
  275. //
  276. // } else if (row.process_status === 3) {
  277. // str += `<button type="button" class="btn btn-icon btn-sm btn-light-danger" data-bs-toggle="tooltip" data-bs-placement="top" title="重新处理" onclick="ReStartProcessTask(${row.id})"><i class="ki-duotone ki-book-square fs-1"><span class="path1"></span><span class="path2"></span><span class="path3"></span></i></button>`
  278. // } else if (row.process_status === 4) {
  279. // str += `<button type="button" class="btn btn-icon btn-sm btn-light-info" data-bs-toggle="tooltip" data-bs-placement="top" title="重新处理" onclick="ReStartProcessTask(${row.id})"><i class="ki-duotone ki-book-square fs-1"><span class="path1"></span><span class="path2"></span><span class="path3"></span></i></button>`
  280. // }
  281. // if (row.send_status === 0) {
  282. // str += `<button type="button" class="btn btn-icon btn-sm btn-light-primary" data-bs-toggle="tooltip" data-bs-placement="top" title="开始发送" onclick="StartSendTask(${row.id})"><i class="ki-duotone ki-send fs-1"><span class="path1"></span><span class="path2"></span></i></button>`
  283. // } else if (row.send_status === 2) {
  284. // str += `<button type="button" class="btn btn-icon btn-sm btn-light-warning" data-bs-toggle="tooltip" data-bs-placement="top" title="重新发送" onclick="ReStartSendTask(${row.id})"><i class="ki-duotone ki-send fs-1"><span class="path1"></span><span class="path2"></span></i></button>`
  285. // } else if (row.send_status === 3) {
  286. // str += `<button type="button" class="btn btn-icon btn-sm btn-light-danger" data-bs-toggle="tooltip" data-bs-placement="top" title="重新发送" onclick="ReStartSendTask(${row.id})"><i class="ki-duotone ki-send fs-1"><span class="path1"></span><span class="path2"></span></i></button>`
  287. // } else if (row.send_status === 4) {
  288. // str += `<button type="button" class="btn btn-icon btn-sm btn-light-info" data-bs-toggle="tooltip" data-bs-placement="top" title="重新发送" onclick="ReStartSendTask(${row.id})"><i class="ki-duotone ki-send fs-1"><span class="path1"></span><span class="path2"></span></i></button>`
  289. // }
  290. } else if (row.process_status === 4) {
  291. str += `<button type="button" class="btn btn-icon btn-sm btn-light-danger" data-bs-toggle="tooltip" data-bs-placement="top" title="重新运行" onclick="ReStarTask(${row.id})"><i class="ki-duotone ki-add-notepad fs-1"><span class="path1"></span><span class="path2"></span><span class="path3"></span><span class="path4"></span></i></button>`
  292. } else if (row.process_status === 5) {
  293. str += `<button type="button" class="btn btn-icon btn-sm btn-light-info" data-bs-toggle="tooltip" data-bs-placement="top" title="重新运行" onclick="ReStarTask(${row.id})"><i class="ki-duotone ki-add-notepad fs-1"><span class="path1"></span><span class="path2"></span><span class="path3"></span><span class="path4"></span></i></button>`
  294. }
  295. if (row.process_status === 0) {
  296. str += `<button type="button" class="btn btn-icon btn-sm btn-light-primary" data-bs-toggle="tooltip" data-bs-placement="top" title="编辑" onclick="Edit(${row.id})"><i class="ki-duotone ki-message-edit fs-1"><span class="path1"></span><span class="path2"></span></i></button>`
  297. }
  298. str += `<!--<button type="button" class="btn btn-icon btn-sm btn-light-primary" data-bs-toggle="tooltip" data-bs-placement="top" title="编辑" onclick="Edit(${row.id})"><i class="ki-duotone ki-message-edit fs-1"><span class="path1"></span><span class="path2"></span></i></button>-->`
  299. if (row.process_status === 2 || row.process_status === 200) {
  300. str += `<button type="button" class="btn btn-icon btn-sm btn-light-primary" data-bs-toggle="tooltip" data-bs-placement="top" title="定额输入列表" onclick="GoTo('/quota_info/${project_id}/${row.id}',0)"><i class="ki-duotone ki-eye fs-1"><span class="path1"></span><span class="path2"></span><span class="path3"></span><span class="path4"></span></i></button>`
  301. }
  302. if (row.process_status !== 2 && row.process_status !== 1) {
  303. str += `<button type="button" class="btn btn-icon btn-sm btn-light-danger" data-bs-toggle="tooltip" data-bs-placement="top" title="删除" onclick="Delete(${row.id})"><i class="ki-duotone ki-trash-square fs-1"><span class="path1"></span><span class="path2"></span><span class="path3"></span><span class="path4"></span></i></button>`
  304. }
  305. return str
  306. }
  307. },
  308. ]
  309. }, true)
  310. $taskBox.find('.table-box').hide()
  311. $taskBox.show()
  312. }
  313. }
  314. function SetBudgetData($el) {
  315. const $tableBox = $(`#body_box .right-box`)
  316. $el.find('[name="project_id"]').val($tableBox.find('input[name="project_id"]').val());
  317. $el.find('[name="item_id"]').val($tableBox.find('input[name="item_id"]').val());
  318. $el.find('[name="item_code"]').val($tableBox.find('input[name="item_code"]').val());
  319. }
  320. function Add() {
  321. _fileUploadDropzone.removeAllFiles()
  322. AddModal($modal, () => {
  323. $modal.find('[name="task_id"]').val('0');
  324. $modal.find('[name="budget_id"]').val(0);
  325. $modal.find('[name="task_sort"]').val(0);
  326. $modal.find('#delete_file_box').hide();
  327. // $modal.find('[name="delete_file"]').prop('checked',false)
  328. SetBudgetData($modal)
  329. })
  330. }
  331. function Edit(id) {
  332. _fileUploadDropzone.removeAllFiles()
  333. EditModal($modal, () => {
  334. IwbAjax_1({
  335. url: `/api/task/get/${id}`,
  336. success: res => {
  337. if (!res.success) {
  338. console.error(res.message)
  339. return
  340. }
  341. const data = res.data
  342. // $modal.find('#delete_file_box').show();
  343. // SetBudgetData(budget_id)
  344. $modal.find('[name="task_id"]').val(data.id);
  345. $modal.find('[name="budget_id"]').val(data.budget_id);
  346. $modal.find('[name="project_id"]').val(data.project_id);
  347. $modal.find('[name="item_id"]').val(data.item_id);
  348. $modal.find('[name="item_code"]').val(data.item_code);
  349. $modal.find('[name="task_name"]').val(data.task_name);
  350. $modal.find('[name="task_desc"]').val(data.task_desc);
  351. $modal.find('[name="task_sort"]').val(data.task_sort);
  352. // $modal.find('[name="delete_file"]').prop('checked',false)
  353. }
  354. })
  355. })
  356. }
  357. function SaveProject(is_submit) {
  358. const
  359. formData = new FormData(),
  360. budget_id = $modal.find('[name="budget_id"]').val(),
  361. item_id = $modal.find('[name="item_id"]').val(),
  362. item_code = $modal.find('[name="item_code"]').val(),
  363. project_id = $modal.find('[name="project_id"]').val(),
  364. task_id = $modal.find('[name="task_id"]').val(),
  365. task_name = $modal.find('[name="task_name"]').val(),
  366. task_sort = $modal.find('[name="task_sort"]').val(),
  367. task_desc = $modal.find('[name="task_desc"]').val(),
  368. // delete_file = $modal.find('[name="delete_file"]').prop('checked')? 'true':'false',
  369. files = _fileUploadDropzone.getAcceptedFiles();
  370. // console.log("FILES",files)
  371. if (files && files.length > 0) {
  372. files.forEach((file) => {
  373. formData.append('files', file)
  374. })
  375. } else {
  376. MsgWarning('文件不能为空,请选择文件')
  377. return
  378. }
  379. formData.append('budget_id', budget_id)
  380. formData.append('item_id', item_id)
  381. formData.append('item_code', item_code)
  382. formData.append('project_id', project_id)
  383. formData.append('task_id', task_id)
  384. formData.append('task_name', task_name)
  385. formData.append('task_sort', task_sort)
  386. formData.append('task_desc', task_desc)
  387. // formData.append('delete_old', delete_file)
  388. if (is_submit) {
  389. formData.append('run_now', 'true')
  390. }
  391. IwbAjax({
  392. url: `/api/task/save/${task_id}`,
  393. headers: {},
  394. body: formData,
  395. modal: "#modal",
  396. table: `#table_0`
  397. })
  398. }
  399. function Delete(id) {
  400. ConfirmUrl('确定删除吗?', `/api/task/delete/${id}`, `#table_0`)
  401. }
  402. function StarTask(id) {
  403. ConfirmUrl('确定开始运行任务吗?', `/api/task/start_task/${id}`, `#table_0`)
  404. }
  405. function ReStarTask(id) {
  406. ConfirmUrl('确定重新开始运行任务吗?', `/api/task/start_task/${id}`, `#table_0`)
  407. }
  408. function CancelTask(id) {
  409. ConfirmUrl('确定取消运行任务吗?', `/api/task/cancel_task/${id}`, `#table_0`)
  410. }
  411. // function StartProcessTask(id){
  412. // ConfirmUrl('确定开始处理吗?',`/api/task/start_process/${id}`,`#table_0`)
  413. // }
  414. //
  415. // function ReStartProcessTask(id){
  416. // ConfirmUrl('确定重新开始处理吗?',`/api/task/start_process/${id}`,`#table_0`)
  417. // }
  418. // function StartSendTask(id){
  419. // ConfirmUrl('确定开始发送吗?',`/api/task/start_send/${id}`,`#table_0`)
  420. // }
  421. // function ReStartSendTask(id){
  422. // ConfirmUrl('确定重新开始发送吗?',`/api/task/start_send/${id}`,`#table_0`)
  423. // }