quota_info.js 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832
  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. canEdit: (row) => {
  368. return row.send_status !== 200
  369. },
  370. trClass: (row) => {
  371. return row.note || !row.quota_code ? 'tr-waring' : ''
  372. },
  373. columns: [
  374. // {
  375. // title: '序号',
  376. // data: 'id',
  377. // width: '80px',
  378. // },
  379. {
  380. title: '条⽬编号',
  381. data: 'item_code',
  382. width: '200px',
  383. tdStyle: "text-align:right;padding-right:15px;",
  384. render: (row) => {
  385. 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>`
  386. }
  387. },
  388. {
  389. title: '工程或费用项目名称',
  390. data: 'entry_name',
  391. width: '255px',
  392. isEdit: true,
  393. render: (row) => {
  394. 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>`
  395. }
  396. },
  397. {
  398. title: '工程数量',
  399. data: 'amount',
  400. width: '100px',
  401. isEdit: true,
  402. },
  403. {
  404. title: '单位',
  405. data: 'units',
  406. width: '80px',
  407. isEdit: true,
  408. },
  409. {
  410. title: '定额编号',
  411. data: 'quota_code',
  412. width: '100px',
  413. isEdit: true,
  414. render: (row) => {
  415. if (!row.quota_code) {
  416. return `<span class="badge badge-light-danger edit-label" data-bs-toggle="tooltip" data-bs-placement="top" title="${row.note ? `说明:${row.note}` : '未查询到'}" ><span class="edit-text">未查询到</span></span>`
  417. }
  418. if (row.quota_id) {
  419. return `<span class="badge badge-light-info edit-label" data-bs-toggle="tooltip" data-bs-placement="top" title="可覆盖系统数据:${row.quota_id} | ${row.note ? `说明:${row.note}` : ''}" ><span class="edit-text">${row.quota_code}</span></span>`
  420. } else {
  421. return `<span class="badge badge-light-primary edit-label" data-bs-toggle="tooltip" data-bs-placement="top" title="未关联系统数据 | ${row.note ? `说明:${row.note}` : ''}" ><span class="edit-text">${row.quota_code}</span></span>`
  422. }
  423. }
  424. },
  425. // {
  426. // title: 'Excel文件',
  427. // data: 'ex_file',
  428. // width: '150px',
  429. // render: (row) => {
  430. // const path = row.ex_file
  431. // if (!path) {
  432. // return '-'
  433. // }
  434. // const names = path.split('/')
  435. // const file_name = names[names.length - 1]
  436. // 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>`
  437. // }
  438. // },
  439. {
  440. title: 'Excel整行内容',
  441. data: 'ex_row',
  442. width: '180px',
  443. render: (row) => {
  444. const ex_row_arr = row.ex_row.split("|"),
  445. ex_row = ex_row_arr[ex_row_arr.length - 1]
  446. return `<span class="one-line" data-bs-toggle="tooltip" data-bs-placement="top" title="${row.ex_row}" >${ex_row}</span>`
  447. }
  448. },
  449. {
  450. title: 'Excel数量',
  451. data: 'ex_amount',
  452. width: '100px',
  453. },
  454. {
  455. title: '数量位置',
  456. data: 'ex_cell',
  457. width: '80px',
  458. },
  459. {
  460. title: '数量单位',
  461. data: 'ex_unit',
  462. width: '80px',
  463. },
  464. {
  465. title: '状态',
  466. data: 'status',
  467. width: '90px',
  468. render: (row) => {
  469. let str = ''
  470. // if(row.process_status === 0){
  471. // str+= `<span class="badge badge-primary">未处理</span>`
  472. // }else if (row.process_status === 1){
  473. // str+= `<span class="badge badge-warning">处理中</span>`
  474. // }else if (row.process_status === 2){
  475. // str+= `<span class="badge badge-success">已处理</span>`
  476. // }else if (row.process_status === 3){
  477. // str+= `<span class="badge badge-danger">处理失败</span>`
  478. // }else if (row.process_status === 4){
  479. // str+= `<span class="badge badge-danger">数据变更</span>`
  480. // }
  481. if (row.send_status === 0) {
  482. str += `<span class="badge badge-primary ms-3">未推送</span>`
  483. } else if (row.send_status === 1) {
  484. str += `<span class="badge badge-warning ms-3">推送中</span>`
  485. } else if (row.send_status === 200) {
  486. str += `<span class="badge badge-success ms-3">推送成功</span>`
  487. } else if (row.send_status === 2) {
  488. str += `<span class="badge badge-danger ms-3" data-bs-toggle="tooltip" data-bs-placement="top" title="${row.send_error}">推送失败</span>`
  489. } else if (row.send_status === 3) {
  490. str += `<span class="badge badge-danger ms-3">数据变更</span>`
  491. }
  492. return str
  493. }
  494. },
  495. {
  496. title: '操作',
  497. data: 'id',
  498. width: '170px',
  499. render: (row) => {
  500. let str = ''
  501. // if (row.process_status === 0) {
  502. // 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>`
  503. // } else if (row.process_status === 2) {
  504. // 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>`
  505. //
  506. // } else if (row.process_status === 3) {
  507. // 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>`
  508. // } else if (row.process_status === 4) {
  509. // 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>`
  510. // }
  511. if (row.send_status === 0) {
  512. 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>`
  513. } else if (row.send_status === 200) {
  514. str = `<span class="text-gray-500">暂无操作</span>`
  515. // 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>`
  516. } else if (row.send_status === 2) {
  517. 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>`
  518. } else if (row.send_status === 3) {
  519. 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>`
  520. }
  521. if (row.send_status !== 200) {
  522. 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>`
  523. 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>`
  524. 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>`
  525. }
  526. return str
  527. }
  528. },
  529. ]
  530. }, true)
  531. }
  532. function SetBudgetData($el) {
  533. const $tableBox = $(`.table-box`)
  534. $el.find('[name="project_id"]').val($tableBox.find('input[name="project_id"]').val());
  535. $el.find('[name="item_id"]').val($tableBox.find('input[name="item_id"]').val());
  536. $el.find('[name="item_code"]').val($tableBox.find('input[name="item_code"]').val());
  537. }
  538. function Add_Quota(budget_id,) {
  539. AddModal($modalQuota, () => {
  540. SetBudgetData($modalQuota)
  541. $modalQuota.find('[name="id"]').val('0');
  542. $modalQuota.find('[name="quota_id"]').val('0');
  543. $modalQuota.find('[name="task_id"]').val('0');
  544. $modalQuota.find('[name="budget_id"]').val(budget_id);
  545. $modalQuota.find('[name="is_cover"]').val('0')
  546. $modalQuota.find('[name="chapter"]').val('').data('id', "").data('code', "").select2tree();
  547. $modalQuota.find('.is_cover_box').hide()
  548. })
  549. }
  550. function Edit_Quota(id) {
  551. $modalQuota.find('.is_cover_box').hide()
  552. EditModal($modalQuota, () => {
  553. IwbAjax_1({
  554. url: `/api/quota/get/${id}`,
  555. success: res => {
  556. if (!res.success) {
  557. console.error(res.message)
  558. return
  559. }
  560. const data = res.data,
  561. // SetBudgetData(budget_id)
  562. quota_id = data.quota_id
  563. $modalQuota.find('[name="id"]').val(data.id);
  564. $modalQuota.find('[name="quota_id"]').val(quota_id);
  565. $modalQuota.find('[name="task_id"]').val(data.task_id);
  566. $modalQuota.find('[name="budget_id"]').val(data.budget_id);
  567. $modalQuota.find('[name="project_id"]').val(data.project_id);
  568. $modalQuota.find('[name="item_id"]').val(data.item_id);
  569. $modalQuota.find('[name="item_code"]').val(data.item_code);
  570. $modalQuota.find('[name="entry_name"]').val(data.entry_name);
  571. $modalQuota.find('[name="amount"]').val(data.amount);
  572. $modalQuota.find('[name="units"]').val(data.units);
  573. $modalQuota.find('[name="quota_code"]').val(data.quota_code);
  574. $modalQuota.find('[name="chapter"]').data('id', data.item_id).data('code', data.item_code).val(data.item_code).select2tree();
  575. $modalQuota.find('#ex_row').html(data.ex_row);
  576. $modalQuota.find('#ex_amount').html(data.ex_amount);
  577. $modalQuota.find('#ex_cell').html(data.ex_cell);
  578. $modalQuota.find('#ex_unit').html(data.ex_unit);
  579. $modalQuota.find('[name="is_cover"][value="0"]').prop('checked', true)
  580. if (quota_id) {
  581. $modalQuota.find('.is_cover_box').show()
  582. }
  583. }
  584. })
  585. })
  586. }
  587. function SaveQuota(isSubmit) {
  588. const id = $modalQuota.find('[name="id"]').val(),
  589. quota_id = $modalQuota.find('[name="quota_id"]').val(),
  590. task_id = $modalQuota.find('[name="task_id"]').val(),
  591. budget_id = $modalQuota.find('[name="budget_id"]').val(),
  592. project_id = $modalQuota.find('[name="project_id"]').val(),
  593. item_id = $modalQuota.find('[name="item_id"]').val(),
  594. item_code = $modalQuota.find('[name="item_code"]').val(),
  595. entry_name = $modalQuota.find('[name="entry_name"]').val(),
  596. amount = $modalQuota.find('[name="amount"]').val(),
  597. units = $modalQuota.find('[name="units"]').val(),
  598. quota_code = $modalQuota.find('[name="quota_code"]').val(),
  599. is_cover = $modalQuota.find('[name="is_cover"]:checked').val(),
  600. chapter = $modalQuota.find('[name="chapter"]').val()
  601. IwbAjax({
  602. url: `/api/quota/save`,
  603. data: {
  604. id,
  605. quota_id,
  606. task_id,
  607. budget_id,
  608. project_id,
  609. item_id,
  610. item_code,
  611. entry_name,
  612. amount,
  613. units,
  614. quota_code,
  615. chapter,
  616. run_now: isSubmit ? 'true' : 'false',
  617. is_cover: is_cover === '1' || is_cover === 1 ? 'true' : 'false',
  618. },
  619. modal: $modalQuota,
  620. table: `#table_${budget_id}`
  621. })
  622. }
  623. function Delete_Quota(id, budget_id) {
  624. ConfirmUrl('确定删除吗?', `/api/quota/delete/${id}`, `#table_${budget_id}`)
  625. }
  626. function StartSendQuota(ids, budget_id, is_cover) {
  627. SendQuota('确定开始推送数据吗?', ids, budget_id, is_cover)
  628. }
  629. function ReStartSendQuota(ids, budget_id, is_cover) {
  630. SendQuota('确定重新开始推送数据吗?', ids, budget_id, is_cover)
  631. }
  632. function Send_Quota_Batch(budget_id) {
  633. const $table = `#table_${budget_id}`,
  634. selectedRows = IwbTableGetSelectedRows($table)
  635. if (selectedRows.length) {
  636. const ids = [], insert_ids = [], update_ids = []
  637. for (let i = 0; i < selectedRows.length; i++) {
  638. const row = selectedRows[i]
  639. if (row.quota_id > 0) {
  640. update_ids.push(row.id)
  641. } else {
  642. insert_ids.push(row.id)
  643. }
  644. ids.push(row.id)
  645. }
  646. const ids_str = ids.join(','), insert_ids_str = insert_ids.join(','), update_ids_str = update_ids.join(',')
  647. let str = `<div class="mb-3 fw-bold">确定批量推送这些数据吗?</div>`
  648. if (insert_ids_str) {
  649. str += `<div class="text-primary d-flex align-items-center"><strong style="white-space: nowrap">新增ID:</strong>${insert_ids_str}</div>`
  650. }
  651. if (update_ids_str) {
  652. str += `<div class="text-danger d-flex align-items-center"><strong style="white-space: nowrap">覆盖(修改)ID:</strong>${update_ids_str}</div>`
  653. }
  654. SendQuota(str, ids_str, budget_id, !!update_ids_str, true)
  655. } else {
  656. MsgWarning('没有选择数据,请选择要推送的数据!')
  657. }
  658. }
  659. function SendQuota(title, ids, budget_id, is_cover, is_html) {
  660. const opts = {
  661. text: title,
  662. icon: "info",
  663. buttonsStyling: false,
  664. showCancelButton: true,
  665. showConfirmButton: true,
  666. showDenyButton: !!is_cover,
  667. cancelButtonText: "取消",
  668. confirmButtonText: "新增",
  669. denyButtonText: "覆盖",
  670. customClass: {
  671. cancelButton: "btn btn-light mx-2",
  672. confirmButton: "btn btn-primary mx-2",
  673. denyButton: "btn btn-danger mx-2"
  674. },
  675. toast: false
  676. }
  677. if (is_html) {
  678. opts.html = `${title}`
  679. }
  680. Swal.fire(opts).then((result) => {
  681. // console.log("CONFIRM", result)
  682. if (result.isConfirmed) {
  683. _send(false)
  684. } else if (result.isDenied) {
  685. _send(true)
  686. }
  687. });
  688. function _send(is_cover) {
  689. // console.log("is_cover", is_cover, ids)
  690. IwbAjax({
  691. url: `/api/quota/start_send`,
  692. data: {
  693. ids: ids + "",
  694. is_cover: is_cover ? 'true' : 'false'
  695. },
  696. modal: $modalQuota,
  697. table: `#table_${budget_id}`
  698. })
  699. }
  700. }
  701. function Edit_Quota_Code_Batch(budget_id) {
  702. const ids = IwbTableGetSelectedIds('#table_' + budget_id).join(",")
  703. if (!ids) {
  704. MsgWarning('没有选择数据,请选择要修改的数据!')
  705. return
  706. }
  707. Swal.fire({
  708. title: '批量修改定额编号',
  709. html: '<input id="batch_quota_code" class="form-control form-control-sm" placeholder="请输入定额编号"/>',
  710. showCancelButton: true,
  711. focusConfirm: false,
  712. confirmButtonText: '修改',
  713. cancelButtonText: '取消',
  714. customClass: {
  715. cancelButton: "btn btn-light",
  716. confirmButton: "btn btn-primary"
  717. },
  718. }).then((result) => {
  719. // console.log("CONFIRM", result)
  720. if (result.isConfirmed) {
  721. IwbAjax({
  722. url: `/api/quota/edit_quota_code_batch`,
  723. data: {
  724. ids,
  725. quota_code: $('#batch_quota_code').val()
  726. },
  727. table: `#table_${budget_id}`
  728. })
  729. }
  730. });
  731. }
  732. function Edit_QuotaChapter(id, budget_id) {
  733. let ids = id
  734. if (!ids) {
  735. ids = IwbTableGetSelectedIds('#table_' + budget_id).join(",")
  736. }
  737. // console.log("Edit_QuotaChapter", ids)
  738. EditModal($modalChapter, () => {
  739. $modalChapter.find('[name="budget_id"]').val(budget_id);
  740. $modalChapter.find('[name="id"]').val(ids);
  741. RenderChapterSelect()
  742. })
  743. }
  744. function RenderChapterSelect() {
  745. const $chapter = $modalChapter.find('[name="chapter"]')
  746. if ($chapter.data('init')) {
  747. return
  748. }
  749. IwbAjax_1({
  750. url: `/api/project/task_chapters/${task_id}`,
  751. success: function (res) {
  752. if (res.success) {
  753. let str = FormatChapterOption(res.data)
  754. $chapter.html(str).data('init', true).select2tree()
  755. } else {
  756. console.error('加载章节出错:', res.message)
  757. }
  758. }
  759. })
  760. }
  761. function FormatChapterOption(data) {
  762. // console.log('FormatChapterOption', data)
  763. let str = ''
  764. if (data && data.length) {
  765. data.forEach(item => {
  766. // let parent_code = get_parent_code(item.item_code)
  767. // console.log('item_code', item.id, item.parent, item.text)
  768. if (item.parent) {
  769. str += `<option data-id="${item.data.item_id}" value="${item.id}" parent="${item.parent}">${item.text}</option>`
  770. } else {
  771. str += `<option data-id="${item.data.item_id}" value="${item.id}">${item.text}</option>`
  772. }
  773. })
  774. }
  775. return str
  776. }
  777. function OnChapterChange() {
  778. // const $this = $modalChapter.find('[name="chapter"]')
  779. // let code = $this.val(), id = $this.find('option[value="' + code + '"]').data('id')
  780. // console.log('OnChapterChange', code, id)
  781. }
  782. function SaveChapterChange() {
  783. const $this = $modalChapter.find('[name="chapter"]'), budget_id = $modalChapter.find('[name="budget_id"]').val()
  784. let code = $this.val(), newId = $this.find('option[value="' + code + '"]').data('id')
  785. if (!newId) {
  786. MsgWarning('请选择章节编号!')
  787. }
  788. IwbAjax_2({
  789. url: `/api/quota/save_change_chapter/${project_id}`,
  790. data: {
  791. ids: $modalChapter.find('[name="id"]').val(),
  792. new_id: newId
  793. }
  794. }, $modalChapter, $('#table_' + budget_id))
  795. }