quota_info.js 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823
  1. const quota_modal_template = `
  2. <div class="modal fade" id="modal_quota" tabindex="-1" aria-hidden="true">
  3. <div class="modal-dialog modal-lg 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="id" value="">
  18. <input type="hidden" name="budget_id" value="">
  19. <input type="hidden" name="project_id" value="">
  20. <input type="hidden" name="item_id" value="">
  21. <input type="hidden" name="item_code" value="">
  22. <input type="hidden" name="quota_id" value="">
  23. <input type="hidden" name="task_id" value="">
  24. <div>
  25. <dl class="d-flex mb-1">
  26. <dt class="" style="white-space: nowrap">源内容:</dt>
  27. <dd id="ex_row" class="ms-3 mb-0"></dd>
  28. </dl>
  29. <div class="d-flex flex-wrap">
  30. <dl class="d-flex mb-1 w-25">
  31. <dt class="" style="white-space: nowrap">源数量:</dt>
  32. <dd id="ex_amount" class="ms-3 mb-0"></dd>
  33. </dl>
  34. <dl class="d-flex mb-1 w-25">
  35. <dt class="" style="white-space: nowrap">源数量位置:</dt>
  36. <dd id="ex_cell" class="ms-3 mb-0"></dd>
  37. </dl>
  38. <dl class="d-flex mb-1 w-25">
  39. <dt class="" style="white-space: nowrap">源数量单位:</dt>
  40. <dd id="ex_unit" class="ms-3 mb-0"></dd>
  41. </dl>
  42. </div>
  43. </div>
  44. <span class="separator my-5"></span>
  45. <div class="fv-row form-group mb-3">
  46. <label for="entry_name" class="form-label required">工程或费用项目名称</label>
  47. <input type="text" class="form-control" name="entry_name" id="entry_name" placeholder="请输入工程或费用项目名称" required />
  48. </div>
  49. <div class="fv-row form-group mb-3">
  50. <label for="units" class="form-label required">单位</label>
  51. <input type="text" class="form-control" name="units" id="units" placeholder="请输入单位" required />
  52. </div>
  53. <div class="fv-row form-group mb-3">
  54. <label for="amount" class="form-label required">工程数量</label>
  55. <input type="text" class="form-control" name="amount" id="amount" placeholder="请输入工程数量" required />
  56. </div>
  57. <div class="fv-row form-group mb-3">
  58. <label for="quota_code" class="form-label">定额编号</label>
  59. <input type="text" class="form-control" name="quota_code" id="quota_code" placeholder="请输入定额编号" />
  60. </div>
  61. <div class="d-flex pt-3 justify-content-center">
  62. <div class="form-check form-check-custom form-check-solid form-check-danger mb-3 is_cover_box">
  63. <input class="form-check-input" type="radio" checked value="1" name="is_cover" id="is_cover_1"/>
  64. <label class="form-check-label ms-3 text-danger" for="is_cover_1">覆盖(修改)源数据</label>
  65. </div>
  66. <div class="form-check form-check-solid ms-5 mb-3 is_cover_box">
  67. <input class="form-check-input" type="radio" value="0" name="is_cover" id="is_cover_2"/>
  68. <label class="form-check-label ms-3 text-primary" for="is_cover_2">新增源数据</label>
  69. </div>
  70. </div>
  71. </div>
  72. </form>
  73. </div>
  74. <div class="modal-footer">
  75. <button type="button" class="btn btn-light" data-bs-dismiss="modal">取消</button>
  76. <button type="button" class="btn btn-light-success" onclick="SaveQuota(true)">提交</button>
  77. <button type="button" class="btn btn-primary" onclick="SaveQuota()">保存草稿</button>
  78. </div>
  79. </div>
  80. </div>
  81. </div>`,
  82. chapter_modal_template = `
  83. <div class="modal fade" id="modal_chapter" tabindex="-1" aria-hidden="true">
  84. <div class="modal-dialog modal-lg modal-dialog-centered">
  85. <div class="modal-content rounded">
  86. <div class="modal-header">
  87. <h3 class="modal-title"><span class="prefix"></span>章节条目</h3>
  88. <div class="btn btn-sm btn-icon btn-active-color-primary" data-bs-dismiss="modal">
  89. <i class="ki-duotone ki-cross fs-1">
  90. <span class="path1"></span>
  91. <span class="path2"></span>
  92. </i>
  93. </div>
  94. </div>
  95. <div class="modal-body">
  96. <form>
  97. <div class="form-group">
  98. <input type="hidden" name="id" value="">
  99. <input type="hidden" name="budget_id" value="">
  100. <input type="hidden" name="project_id" value="">
  101. <input type="hidden" name="item_id" value="">
  102. <input type="hidden" name="item_code" value="">
  103. <input type="hidden" name="quota_id" value="">
  104. <input type="hidden" name="task_id" value="">
  105. <div class="fv-row form-group mb-3">
  106. <label for="quota_code" class="form-label">章节条目</label>
  107. <select type="text" class="form-select" name="chapter" onchange="OnChapterChange()"></select>
  108. </div>
  109. </div>
  110. </form>
  111. </div>
  112. <div class="modal-footer">
  113. <button type="button" class="btn btn-light" data-bs-dismiss="modal">取消</button>
  114. <button type="button" class="btn btn-light-success" onclick="SaveChapterChange()">保存</button>
  115. </div>
  116. </div>
  117. </div>
  118. </div>
  119. `
  120. $('.app-main .app-container').append(quota_modal_template)
  121. $('.app-main .app-container').append(chapter_modal_template)
  122. const nav_template = `<ul id="nav_tab" class="nav nav-tabs nav-line-tabs nav-line-tabs-2x fs-6"></ul><div class="tab-content" id="tab_content" style="height: calc(100% - 80px);"></div>`,
  123. nav_tab_template = `
  124. <li class="nav-item" data-id="{0}">
  125. <button type="button" class="nav-link {2} btn-light-primary btn-active-color-primary" data-id="{0}" data-bs-toggle="tab" data-bs-target="#iwb_tab_{0}">{1}</button>
  126. </li>`,
  127. tab_content_template = `<div class="tab-pane h-100" id="iwb_tab_{0}" role="tabpanel">{1}</div>`,
  128. table_run_select_template = `<select class="form-select form-select-sm me-5" name="process_status" data-placeholder="请选择运行状态">
  129. <option value="">全部运行状态</option>
  130. <option value="0">草稿</option>
  131. <option value="1">等待运行</option>
  132. <option value="2">运行中</option>
  133. <option value="200">运行成功</option>
  134. <option value="4">取消运行</option>
  135. <option value="5">运行失败</option>
  136. <!--<option value="4">已修改</option>-->
  137. </select>`,
  138. table_send_select_template = `<select class="form-select form-select-sm me-5" name="send_status" data-placeholder="请选择推送状态">
  139. <option value="">全部推送状态</option>
  140. <option value="0">未推送</option>
  141. <!-- <option value="1">推送中</option>-->
  142. <option value="200">推送成功</option>
  143. <option value="2">推送失败</option>
  144. <!-- <option value="3">数据变更</option>-->
  145. </select>`,
  146. table_template = `<div class="table-box table-responsive" data-id="{0}" id="table_box_{0}">
  147. <div class="d-flex justify-content-between my-5">
  148. <div class="">{1}</div>
  149. <form class="search-box d-flex">
  150. <div class="d-flex">
  151. {2}
  152. <input type="text" class="form-control form-control-sm w-200px" placeholder="请输入关键字" name="keyword" />
  153. </div>
  154. <div class="btn-group ms-5">
  155. <button type="button" class="btn btn-primary btn-sm" onclick="IwbTableSearch(this);clear()">查询</button>
  156. <button type="button" class="btn btn-danger btn-sm" onclick="IwbTableResetSearch(this);clear()">重置</button>
  157. </div>
  158. </form>
  159. </div>
  160. <div class="pagination-row"></div>
  161. <table class="table table-striped table-bordered table-hover table-rounded" id="table_{0}">
  162. </table>
  163. </div>`
  164. let table_add_quota_btn_template = `<button type="button" class="quota_add_btn btn btn-primary btn-sm" onclick="Send_Quota_Batch('{0}')">批量推送</button>`;
  165. table_add_quota_btn_template += `<button type="button" class="ms-5 btn btn-warning btn-sm" onclick="Edit_Quota_Code_Batch('{0}')">批量修改定额编号</button>`
  166. // table_add_quota_btn_template += `<button type="button" class="ms-5 btn btn-warning btn-sm" onclick="Edit_QuotaChapter(null,'{0}')">批量修改章节</button>`
  167. //`<button type="button" class="quota_add_btn btn btn-primary btn-sm" onclick="Add_Quota('{0}')">添加定额</button>`
  168. const $modalQuota = $('#modal_quota'), $modalChapter = $('#modal_chapter')
  169. let $rightBox, $rightBoxHeader, $rightBoxBody, $taskBox, $quotaBox, budget_id, item_code, task_timer,
  170. task_query_count = 0
  171. console.log(`加载项目:${project_id}${task_id ? `,任务ID:${task_id}。` : ''}`)
  172. InitBody()
  173. function clear() {
  174. task_query_count = 0
  175. clearTimeout(task_timer)
  176. }
  177. $(function () {
  178. BuildChapterInfo()
  179. $(window).on('resize', AdjustBoxHeight)
  180. if (task_id) {
  181. RenderChapterSelect()
  182. }
  183. })
  184. function InitBody() {
  185. $('#body_box').html(`<div class="d-flex flex-row project-box w-100">
  186. <div class="flex-row-auto h-100 left-box">
  187. <div class="tree-dom w-300px h-100 overflow-auto" id="js-tree"></div>
  188. </div>
  189. <div class="flex-row-fluid flex-column right-box" style="display: none">
  190. <div class="my-2 d-flex align-items-center box-header mt-5 flex-column-auto">
  191. <section class="d-none">
  192. <input type="hidden" name="budget_id" value="{0}">
  193. <input type="hidden" name="project_id" value="">
  194. <input type="hidden" name="item_id" value="">
  195. <input type="hidden" name="item_code" value="">
  196. </section>
  197. <span class="fw-bolder me-5 title fs-2"></span>
  198. <span class="badge badge-primary fs-6 me-5"></span>
  199. <div class="d-flex table_radio_box" >
  200. <div class="form-check form-check-custom form-check-primary form-check-solid">
  201. <input class="form-check-input" name="table_radio" type="radio" value="task" id="task_radio"/>
  202. <label class="form-check-label fw-bolder text-primary" for="task_radio">
  203. 任务列表
  204. </label>
  205. </div>
  206. <div class="form-check form-check-custom form-check-success form-check-solid ms-5">
  207. <input class="form-check-input" name="table_radio" type="radio" value="quota" id="quota_radio"/>
  208. <label class="form-check-label fw-bolder text-success" for="quota_radio">
  209. 定额输入
  210. </label>
  211. </div>
  212. </div>
  213. </div>
  214. <div class="box-body flex-column-fluid">
  215. <div class="task w-100 h-100" style="display: none"></div>
  216. <div class="quota w-100 h-100" style="display: none"></div>
  217. </div>
  218. </div>
  219. </div>`)
  220. AdjustBoxHeight()
  221. $rightBox = $('#body_box .right-box'),
  222. $rightBoxHeader = $('#body_box .right-box .box-header'),
  223. $rightBoxBody = $('#body_box .right-box .box-body'),
  224. $taskBox = $rightBoxBody.find('.task'),
  225. $quotaBox = $rightBoxBody.find('.quota')
  226. }
  227. function AdjustBoxHeight() {
  228. const h = $('.app-wrapper').height() - $('.app-body-header').height() - $('.app-footer').height() - 5
  229. $('#body_box .project-box').height(h)
  230. }
  231. function BuildChapterInfo() {
  232. const $tree = $(`#js-tree`), taskId = task_id || ""
  233. const opt = {
  234. core: {
  235. themes: {
  236. responsive: false,
  237. },
  238. strings: {
  239. 'Loading ...': '加载中...',
  240. },
  241. check_callback: true,
  242. data: function (node, callback) {
  243. // console.log('TREE_NODE', node)
  244. IwbAjax_1({
  245. url: `/api/project/chapter/${project_id}?c=${node?.data?.item_code || ''}&&t=${taskId}`,
  246. success: res => {
  247. if (res.success) {
  248. // console.log('TREE', res.data)
  249. callback(res.data)
  250. } else {
  251. console.error(res.message)
  252. }
  253. },
  254. })
  255. },
  256. },
  257. types: {
  258. default: {
  259. icon: 'ki-outline ki-folder text-primary',
  260. },
  261. file: {
  262. icon: 'ki-outline ki-file text-primary',
  263. },
  264. },
  265. plugins: ['dnd', 'types'],
  266. }
  267. // $tree.jstree('destroy')
  268. $tree.on('loaded.jstree', function (e, data) {
  269. // console.log('TREE_LOADED', e, data)
  270. const inst = data.instance;
  271. const obj = inst.get_node(e.target.firstChild.firstChild.firstChild);
  272. inst.select_node(obj);
  273. })
  274. $tree.on('select_node.jstree', function (e, data) {
  275. // console.log('TREE_SELECTED', e, data)
  276. RenderRightBox(data.node?.data)
  277. })
  278. $tree.jstree(opt)
  279. }
  280. function RenderRightBox(data) {
  281. // console.log('RenderRightBox', arguments)
  282. $rightBoxBody.data('data', data)
  283. clear()
  284. $rightBox.find('input[name="budget_id"]').val(data.budget_id);
  285. $rightBox.find('input[name="project_id"]').val(project_id);
  286. $rightBox.find('input[name="item_id"]').val(data.item_id);
  287. $rightBox.find('input[name="item_code"]').val(data.item_code);
  288. const title = data.chapter ? `${data.chapter}、${data.project_name}` : data.section ? `${data.section}.${data.project_name}` : data.project_name
  289. $rightBoxHeader.find('.title').text(title)
  290. RenderRightBox_Custom(data)
  291. $rightBox.show()
  292. }
  293. function RenderRightBox_Custom(data) {
  294. $('.table_radio_box .form-check').hide()
  295. $quotaBox.data("table-url", `/api/quota/list/task/${task_id}`)
  296. QuotaNavTab(data)
  297. }
  298. function QuotaNavTab() {
  299. $taskBox.hide()
  300. if (!$quotaBox.find('#nav_tab').length) {
  301. $quotaBox.html(nav_template)
  302. BuildBudgetInfo()
  303. } else {
  304. const budget = $quotaBox.find('#nav_tab').data('budget-info') || {}
  305. $quotaBox.html(nav_template)
  306. RenderTabs(budget)
  307. }
  308. $quotaBox.find('.table-box').hide()
  309. $quotaBox.show()
  310. }
  311. function BuildBudgetInfo() {
  312. IwbAjax_1({
  313. url: `/api/project/budget/${project_id}`,
  314. success: function (res) {
  315. if (res.success) {
  316. RenderTabs(res.data)
  317. } else {
  318. console.error(res.message)
  319. }
  320. },
  321. })
  322. }
  323. function RenderTabs(data) {
  324. // console.log('RenderTabs', data)
  325. let str1 = '',
  326. str2 = ''
  327. if (data && data.length) {
  328. for (let i = 0; i < data.length; i++) {
  329. const item = data[i]
  330. str1 += nav_tab_template.format(item.budget_id, item.budget_code)
  331. const tableStr = table_template.format(item.budget_id, table_add_quota_btn_template.format(item.budget_id), table_send_select_template)
  332. const tabContent = tab_content_template.format(item.budget_id, tableStr)
  333. // console.log('TAB_CONTENT', tabContent)
  334. str2 += tabContent
  335. }
  336. }
  337. const $tab = $('#nav_tab'), $content = $('#tab_content')
  338. $tab.html(str1).data('budget-info', data)
  339. $content.html(str2)
  340. const $tab_btn = $tab.find('li button[data-bs-toggle="tab"]')
  341. $tab_btn.on('shown.bs.tab', (e) => {
  342. // console.log('TAB', e)
  343. const tab_id = $(e.target).data('id'),
  344. data = $("#body_box .right-box .box-body").data('data')
  345. budget_id = tab_id
  346. item_code = data.item_code
  347. RenderQuotaTable(data)
  348. })
  349. const firstTab = new bootstrap.Tab($tab_btn.eq(0))
  350. firstTab.show()
  351. }
  352. function RenderQuotaTable(data) {
  353. // console.log('RenderQuotaTable', budget_id, data)
  354. const $table = $quotaBox.find(`#table_${budget_id}`)
  355. LoadQuotaTable($table)
  356. }
  357. function LoadQuotaTable(table) {
  358. const url = `${$quotaBox.data("table-url")}/${budget_id}/${project_id}/${item_code}`
  359. IwbTable(table, {
  360. url,
  361. editUrl: '/api/quota/edit',
  362. checkBox: true,
  363. isDragColumn: true,
  364. checkBoxDisable: (row) => {
  365. return row.send_status === 200
  366. },
  367. columns: [
  368. // {
  369. // title: '序号',
  370. // data: 'id',
  371. // width: '80px',
  372. // },
  373. {
  374. title: '条⽬编号',
  375. data: 'item_code',
  376. width: '200px',
  377. tdStyle: "text-align:right;padding-right:15px;",
  378. render: (row) => {
  379. return `<span class="one-line edit-label" data-bs-toggle="tooltip" data-bs-placement="top" title="${row.item_code}" ><span class="edit-text">${row.item_code}</span></span>`
  380. }
  381. },
  382. {
  383. title: '工程或费用项目名称',
  384. data: 'entry_name',
  385. width: '255px',
  386. isEdit: true,
  387. render: (row) => {
  388. return `<span class="one-line edit-label" data-bs-toggle="tooltip" data-bs-placement="top" title="${row.entry_name}" ><span class="edit-text">${row.entry_name}</span></span>`
  389. }
  390. },
  391. {
  392. title: '工程数量',
  393. data: 'amount',
  394. width: '100px',
  395. isEdit: true,
  396. },
  397. {
  398. title: '单位',
  399. data: 'units',
  400. width: '80px',
  401. isEdit: true,
  402. },
  403. {
  404. title: '定额编号',
  405. data: 'quota_code',
  406. width: '100px',
  407. isEdit: true,
  408. render: (row) => {
  409. if (row.quota_id) {
  410. return `<span class="badge badge-light-danger edit-label" data-bs-toggle="tooltip" data-bs-placement="top" title="可覆盖系统数据:${row.quota_id}" ><span class="edit-text">${row.quota_code}</span></span>`
  411. } else {
  412. return `<span class="badge badge-light-primary edit-label" data-bs-toggle="tooltip" data-bs-placement="top" title="未关联系统数据" ><span class="edit-text">${row.quota_code}</span></span>`
  413. }
  414. }
  415. },
  416. // {
  417. // title: 'Excel文件',
  418. // data: 'ex_file',
  419. // width: '150px',
  420. // render: (row) => {
  421. // const path = row.ex_file
  422. // if (!path) {
  423. // return '-'
  424. // }
  425. // const names = path.split('/')
  426. // const file_name = names[names.length - 1]
  427. // return `<span class="one-line mw-150px"><a href="#" onclick="DownloadFile('/api/task/download?filename=${encodeURIComponent(path)}','${file_name}')" class="link link-info px-2">${file_name}</a></span>`
  428. // }
  429. // },
  430. {
  431. title: 'Excel整行内容',
  432. data: 'ex_row',
  433. width: '180px',
  434. render: (row) => {
  435. const ex_row_arr = row.ex_row.split("|"),
  436. ex_row = ex_row_arr[ex_row_arr.length - 1]
  437. return `<span class="one-line" data-bs-toggle="tooltip" data-bs-placement="top" title="${row.ex_row}" >${ex_row}</span>`
  438. }
  439. },
  440. {
  441. title: 'Excel数量',
  442. data: 'ex_amount',
  443. width: '100px',
  444. },
  445. {
  446. title: '数量位置',
  447. data: 'ex_cell',
  448. width: '80px',
  449. },
  450. {
  451. title: '数量单位',
  452. data: 'ex_unit',
  453. width: '80px',
  454. },
  455. {
  456. title: '状态',
  457. data: 'status',
  458. width: '90px',
  459. render: (row) => {
  460. let str = ''
  461. // if(row.process_status === 0){
  462. // str+= `<span class="badge badge-primary">未处理</span>`
  463. // }else if (row.process_status === 1){
  464. // str+= `<span class="badge badge-warning">处理中</span>`
  465. // }else if (row.process_status === 2){
  466. // str+= `<span class="badge badge-success">已处理</span>`
  467. // }else if (row.process_status === 3){
  468. // str+= `<span class="badge badge-danger">处理失败</span>`
  469. // }else if (row.process_status === 4){
  470. // str+= `<span class="badge badge-danger">数据变更</span>`
  471. // }
  472. if (row.send_status === 0) {
  473. str += `<span class="badge badge-primary ms-3">未推送</span>`
  474. } else if (row.send_status === 1) {
  475. str += `<span class="badge badge-warning ms-3">推送中</span>`
  476. } else if (row.send_status === 200) {
  477. str += `<span class="badge badge-success ms-3">推送成功</span>`
  478. } else if (row.send_status === 2) {
  479. str += `<span class="badge badge-danger ms-3" data-bs-toggle="tooltip" data-bs-placement="top" title="${row.send_error}">推送失败</span>`
  480. } else if (row.send_status === 3) {
  481. str += `<span class="badge badge-danger ms-3">数据变更</span>`
  482. }
  483. return str
  484. }
  485. },
  486. {
  487. title: '操作',
  488. data: 'id',
  489. width: '170px',
  490. render: (row) => {
  491. let str = ''
  492. // if (row.process_status === 0) {
  493. // str += `<button type="button" class="btn btn-icon btn-sm btn-light-primary" data-bs-toggle="tooltip" data-bs-placement="top" title="开始处理" onclick="StartProcessQuota(${row.id}, ${row.budget_id})"><i class="ki-duotone ki-book-square fs-1"><span class="path1"></span><span class="path2"></span><span class="path3"></span></i></button>`
  494. // } else if (row.process_status === 2) {
  495. // str += `<button type="button" class="btn btn-icon btn-sm btn-light-warning" data-bs-toggle="tooltip" data-bs-placement="top" title="重新处理" onclick="ReStartProcessQuota(${row.id}, ${row.budget_id})"><i class="ki-duotone ki-book-square fs-1"><span class="path1"></span><span class="path2"></span><span class="path3"></span></i></button>`
  496. //
  497. // } else if (row.process_status === 3) {
  498. // str += `<button type="button" class="btn btn-icon btn-sm btn-light-danger" data-bs-toggle="tooltip" data-bs-placement="top" title="重新处理" onclick="ReStartProcessQuota(${row.id}, ${row.budget_id})"><i class="ki-duotone ki-book-square fs-1"><span class="path1"></span><span class="path2"></span><span class="path3"></span></i></button>`
  499. // } else if (row.process_status === 4) {
  500. // str += `<button type="button" class="btn btn-icon btn-sm btn-light-info" data-bs-toggle="tooltip" data-bs-placement="top" title="重新处理" onclick="ReStartProcessQuota(${row.id}, ${row.budget_id})"><i class="ki-duotone ki-book-square fs-1"><span class="path1"></span><span class="path2"></span><span class="path3"></span></i></button>`
  501. // }
  502. if (row.send_status === 0) {
  503. str += `<button type="button" class="btn btn-icon btn-sm ${row.quota_id ? 'btn-primary' : 'btn-light-primary'}" data-bs-toggle="tooltip" data-bs-placement="top" title="开始推送" onclick="StartSendQuota(${row.id}, ${row.budget_id}, ${row.quota_id})"><i class="ki-duotone ki-send fs-3"><span class="path1"></span><span class="path2"></span></i></button>`
  504. } else if (row.send_status === 200) {
  505. str = `<span class="text-gray-500">暂无操作</span>`
  506. // str += `<button type="button" class="btn btn-icon btn-sm ${row.quota_id ? 'btn-warning' : 'btn-light-warning'}" data-bs-toggle="tooltip" data-bs-placement="top" title="重新推送" onclick="ReStartSendQuota(${row.id}, ${row.budget_id}, ${row.quota_id})"><i class="ki-duotone ki-send fs-3"><span class="path1"></span><span class="path2"></span></i></button>`
  507. } else if (row.send_status === 2) {
  508. str += `<button type="button" class="btn btn-icon btn-sm ${row.quota_id ? 'btn-danger' : 'btn-light-danger'}" data-bs-toggle="tooltip" data-bs-placement="top" title="重新推送" onclick="ReStartSendQuota(${row.id}, ${row.budget_id}, ${row.quota_id})"><i class="ki-duotone ki-send fs-3"><span class="path1"></span><span class="path2"></span></i></button>`
  509. } else if (row.send_status === 3) {
  510. str += `<button type="button" class="btn btn-icon btn-sm ${row.quota_id ? 'btn-info' : 'btn-light-info'}" data-bs-toggle="tooltip" data-bs-placement="top" title="重新推送" onclick="ReStartSendQuota(${row.id}, ${row.budget_id}, ${row.quota_id})"><i class="ki-duotone ki-send fs-3"><span class="path1"></span><span class="path2"></span></i></button>`
  511. }
  512. if (row.send_status !== 200) {
  513. str += `<button type="button" class="btn btn-icon btn-sm btn-light-primary" data-bs-toggle="tooltip" data-bs-placement="top" title="编辑" onclick="Edit_Quota(${row.id}, ${row.budget_id})"><i class="ki-duotone ki-message-edit fs-1"><span class="path1"></span><span class="path2"></span></i></button>`
  514. str += `<button type="button" class="btn btn-icon btn-sm btn-light-primary" data-bs-toggle="tooltip" data-bs-placement="top" title="修改条目" onclick="Edit_QuotaChapter(${row.id}, ${row.budget_id})"><i class="ki-duotone ki-burger-menu-1 fs-1"><span class="path1"></span><span class="path2"></span><span class="path3"></span><span class="path4"></span></i></button>`
  515. str += `<button type="button" class="btn btn-icon btn-sm btn-light-danger" data-bs-toggle="tooltip" data-bs-placement="top" title="删除" onclick="Delete_Quota(${row.id}, ${row.budget_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>`
  516. }
  517. return str
  518. }
  519. },
  520. ]
  521. }, true)
  522. }
  523. function SetBudgetData($el) {
  524. const $tableBox = $(`.table-box`)
  525. $el.find('[name="project_id"]').val($tableBox.find('input[name="project_id"]').val());
  526. $el.find('[name="item_id"]').val($tableBox.find('input[name="item_id"]').val());
  527. $el.find('[name="item_code"]').val($tableBox.find('input[name="item_code"]').val());
  528. }
  529. function Add_Quota(budget_id,) {
  530. AddModal($modalQuota, () => {
  531. SetBudgetData($modalQuota)
  532. $modalQuota.find('[name="id"]').val('0');
  533. $modalQuota.find('[name="quota_id"]').val('0');
  534. $modalQuota.find('[name="task_id"]').val('0');
  535. $modalQuota.find('[name="budget_id"]').val(budget_id);
  536. $modalQuota.find('[name="is_cover"]').val('0')
  537. $modalQuota.find('[name="chapter"]').val('').data('id', "").data('code', "").select2tree();
  538. $modalQuota.find('.is_cover_box').hide()
  539. })
  540. }
  541. function Edit_Quota(id) {
  542. $modalQuota.find('.is_cover_box').hide()
  543. EditModal($modalQuota, () => {
  544. IwbAjax_1({
  545. url: `/api/quota/get/${id}`,
  546. success: res => {
  547. if (!res.success) {
  548. console.error(res.message)
  549. return
  550. }
  551. const data = res.data,
  552. // SetBudgetData(budget_id)
  553. quota_id = data.quota_id
  554. $modalQuota.find('[name="id"]').val(data.id);
  555. $modalQuota.find('[name="quota_id"]').val(quota_id);
  556. $modalQuota.find('[name="task_id"]').val(data.task_id);
  557. $modalQuota.find('[name="budget_id"]').val(data.budget_id);
  558. $modalQuota.find('[name="project_id"]').val(data.project_id);
  559. $modalQuota.find('[name="item_id"]').val(data.item_id);
  560. $modalQuota.find('[name="item_code"]').val(data.item_code);
  561. $modalQuota.find('[name="entry_name"]').val(data.entry_name);
  562. $modalQuota.find('[name="amount"]').val(data.amount);
  563. $modalQuota.find('[name="units"]').val(data.units);
  564. $modalQuota.find('[name="quota_code"]').val(data.quota_code);
  565. $modalQuota.find('[name="chapter"]').data('id', data.item_id).data('code', data.item_code).val(data.item_code).select2tree();
  566. $modalQuota.find('#ex_row').html(data.ex_row);
  567. $modalQuota.find('#ex_amount').html(data.ex_amount);
  568. $modalQuota.find('#ex_cell').html(data.ex_cell);
  569. $modalQuota.find('#ex_unit').html(data.ex_unit);
  570. $modalQuota.find('[name="is_cover"][value="0"]').prop('checked', true)
  571. if (quota_id) {
  572. $modalQuota.find('.is_cover_box').show()
  573. }
  574. }
  575. })
  576. })
  577. }
  578. function SaveQuota(isSubmit) {
  579. const id = $modalQuota.find('[name="id"]').val(),
  580. quota_id = $modalQuota.find('[name="quota_id"]').val(),
  581. task_id = $modalQuota.find('[name="task_id"]').val(),
  582. budget_id = $modalQuota.find('[name="budget_id"]').val(),
  583. project_id = $modalQuota.find('[name="project_id"]').val(),
  584. item_id = $modalQuota.find('[name="item_id"]').val(),
  585. item_code = $modalQuota.find('[name="item_code"]').val(),
  586. entry_name = $modalQuota.find('[name="entry_name"]').val(),
  587. amount = $modalQuota.find('[name="amount"]').val(),
  588. units = $modalQuota.find('[name="units"]').val(),
  589. quota_code = $modalQuota.find('[name="quota_code"]').val(),
  590. is_cover = $modalQuota.find('[name="is_cover"]:checked').val(),
  591. chapter = $modalQuota.find('[name="chapter"]').val()
  592. IwbAjax({
  593. url: `/api/quota/save`,
  594. data: {
  595. id,
  596. quota_id,
  597. task_id,
  598. budget_id,
  599. project_id,
  600. item_id,
  601. item_code,
  602. entry_name,
  603. amount,
  604. units,
  605. quota_code,
  606. chapter,
  607. run_now: isSubmit ? 'true' : 'false',
  608. is_cover: is_cover === '1' || is_cover === 1 ? 'true' : 'false',
  609. },
  610. modal: $modalQuota,
  611. table: `#table_${budget_id}`
  612. })
  613. }
  614. function Delete_Quota(id, budget_id) {
  615. ConfirmUrl('确定删除吗?', `/api/quota/delete/${id}`, `#table_${budget_id}`)
  616. }
  617. function StartSendQuota(ids, budget_id, is_cover) {
  618. SendQuota('确定开始推送数据吗?', ids, budget_id, is_cover)
  619. }
  620. function ReStartSendQuota(ids, budget_id, is_cover) {
  621. SendQuota('确定重新开始推送数据吗?', ids, budget_id, is_cover)
  622. }
  623. function Send_Quota_Batch(budget_id) {
  624. const $table = `#table_${budget_id}`,
  625. selectedRows = IwbTableGetSelectedRows($table)
  626. if (selectedRows.length) {
  627. const ids = [], insert_ids = [], update_ids = []
  628. for (let i = 0; i < selectedRows.length; i++) {
  629. const row = selectedRows[i]
  630. if (row.quota_id > 0) {
  631. update_ids.push(row.id)
  632. } else {
  633. insert_ids.push(row.id)
  634. }
  635. ids.push(row.id)
  636. }
  637. const ids_str = ids.join(','), insert_ids_str = insert_ids.join(','), update_ids_str = update_ids.join(',')
  638. let str = `<div class="mb-3 fw-bold">确定批量推送这些数据吗?</div>`
  639. if (insert_ids_str) {
  640. str += `<div class="text-primary d-flex align-items-center"><strong style="white-space: nowrap">新增ID:</strong>${insert_ids_str}</div>`
  641. }
  642. if (update_ids_str) {
  643. str += `<div class="text-danger d-flex align-items-center"><strong style="white-space: nowrap">覆盖(修改)ID:</strong>${update_ids_str}</div>`
  644. }
  645. SendQuota(str, ids_str, budget_id, !!update_ids_str, true)
  646. } else {
  647. MsgWarning('没有选择数据,请选择要推送的数据!')
  648. }
  649. }
  650. function SendQuota(title, ids, budget_id, is_cover, is_html) {
  651. const opts = {
  652. text: title,
  653. icon: "info",
  654. buttonsStyling: false,
  655. showCancelButton: true,
  656. showConfirmButton: true,
  657. showDenyButton: !!is_cover,
  658. cancelButtonText: "取消",
  659. confirmButtonText: "新增",
  660. denyButtonText: "覆盖",
  661. customClass: {
  662. cancelButton: "btn btn-light mx-2",
  663. confirmButton: "btn btn-primary mx-2",
  664. denyButton: "btn btn-danger mx-2"
  665. },
  666. toast: false
  667. }
  668. if (is_html) {
  669. opts.html = `${title}`
  670. }
  671. Swal.fire(opts).then((result) => {
  672. // console.log("CONFIRM", result)
  673. if (result.isConfirmed) {
  674. _send(false)
  675. } else if (result.isDenied) {
  676. _send(true)
  677. }
  678. });
  679. function _send(is_cover) {
  680. // console.log("is_cover", is_cover, ids)
  681. IwbAjax({
  682. url: `/api/quota/start_send`,
  683. data: {
  684. ids: ids + "",
  685. is_cover: is_cover ? 'true' : 'false'
  686. },
  687. modal: $modalQuota,
  688. table: `#table_${budget_id}`
  689. })
  690. }
  691. }
  692. function Edit_Quota_Code_Batch(budget_id) {
  693. const ids = IwbTableGetSelectedIds('#table_' + budget_id).join(",")
  694. if (!ids) {
  695. MsgWarning('没有选择数据,请选择要修改的数据!')
  696. return
  697. }
  698. Swal.fire({
  699. title: '批量修改定额编号',
  700. html: '<input id="batch_quota_code" class="form-control form-control-sm" placeholder="请输入定额编号"/>',
  701. showCancelButton: true,
  702. focusConfirm: false,
  703. confirmButtonText: '修改',
  704. cancelButtonText: '取消',
  705. customClass: {
  706. cancelButton: "btn btn-light",
  707. confirmButton: "btn btn-primary"
  708. },
  709. }).then((result) => {
  710. // console.log("CONFIRM", result)
  711. if (result.isConfirmed) {
  712. IwbAjax({
  713. url: `/api/quota/edit_quota_code_batch`,
  714. data: {
  715. ids,
  716. quota_code: $('#batch_quota_code').val()
  717. },
  718. table: `#table_${budget_id}`
  719. })
  720. }
  721. });
  722. }
  723. function Edit_QuotaChapter(id, budget_id) {
  724. let ids = id
  725. if (!ids) {
  726. ids = IwbTableGetSelectedIds('#table_' + budget_id).join(",")
  727. }
  728. // console.log("Edit_QuotaChapter", ids)
  729. EditModal($modalChapter, () => {
  730. $modalChapter.find('[name="budget_id"]').val(budget_id);
  731. $modalChapter.find('[name="id"]').val(ids);
  732. RenderChapterSelect()
  733. })
  734. }
  735. function RenderChapterSelect() {
  736. const $chapter = $modalChapter.find('[name="chapter"]')
  737. if ($chapter.data('init')) {
  738. return
  739. }
  740. IwbAjax_1({
  741. url: `/api/project/task_chapters/${task_id}`,
  742. success: function (res) {
  743. if (res.success) {
  744. let str = FormatChapterOption(res.data)
  745. $chapter.html(str).data('init', true).select2tree()
  746. } else {
  747. console.error('加载章节出错:', res.message)
  748. }
  749. }
  750. })
  751. }
  752. function FormatChapterOption(data) {
  753. // console.log('FormatChapterOption', data)
  754. let str = ''
  755. if (data && data.length) {
  756. data.forEach(item => {
  757. // let parent_code = get_parent_code(item.item_code)
  758. // console.log('item_code', item.id, item.parent, item.text)
  759. if (item.parent) {
  760. str += `<option data-id="${item.data.item_id}" value="${item.id}" parent="${item.parent}">${item.text}</option>`
  761. } else {
  762. str += `<option data-id="${item.data.item_id}" value="${item.id}">${item.text}</option>`
  763. }
  764. })
  765. }
  766. return str
  767. }
  768. function OnChapterChange() {
  769. // const $this = $modalChapter.find('[name="chapter"]')
  770. // let code = $this.val(), id = $this.find('option[value="' + code + '"]').data('id')
  771. // console.log('OnChapterChange', code, id)
  772. }
  773. function SaveChapterChange() {
  774. const $this = $modalChapter.find('[name="chapter"]'), budget_id = $modalChapter.find('[name="budget_id"]').val()
  775. let code = $this.val(), newId = $this.find('option[value="' + code + '"]').data('id')
  776. if (!newId) {
  777. MsgWarning('请选择章节编号!')
  778. }
  779. IwbAjax_2({
  780. url: `/api/quota/save_change_chapter/${project_id}`,
  781. data: {
  782. ids: $modalChapter.find('[name="id"]').val(),
  783. new_id: newId
  784. }
  785. }, $modalChapter, $('#table_' + budget_id))
  786. }