advance_audit.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. 'use strict';
  2. /**
  3. *
  4. *
  5. * @author lanjianrong
  6. * @date 2020/8/7
  7. * @version
  8. */
  9. $(document).ready(function () {
  10. autoFlashHeight()
  11. let oldVal = null
  12. let timer = null
  13. let oldSearchVal = null
  14. handleFileList(fileList)
  15. // 控制上报弹窗的文案
  16. function checkModal(isHide) {
  17. $('#start-modal').empty()
  18. if (isHide) {
  19. // 隐藏上传按钮
  20. $('#start-modal').append('<p class="text-danger">无法上报,请设置审批流程。</p>')
  21. $('#tm-submit').hide()
  22. } else {
  23. $('#start-modal').append(`<p>确认上报第${advance.order}期${advance.type === 0 ? '开工' : '材料'}预付款?</p>`)
  24. $('#tm-submit').show()
  25. }
  26. }
  27. $('#gr-search').bind('input propertychange', function(e) {
  28. oldSearchVal = e.target.value
  29. timer && clearTimeout(timer)
  30. timer = setTimeout(() => {
  31. const newVal = $('#gr-search').val()
  32. let html = ''
  33. if (newVal && newVal === oldSearchVal) {
  34. accountList.filter(item => item && cur_uid !== item.id && (item.name.indexOf(newVal) !== -1 || (item.mobile && item.mobile.indexOf(newVal) !== -1))).forEach(item => {
  35. html += `<dd class="border-bottom p-2 mb-0 " data-id="${item.id}" >
  36. <p class="mb-0 d-flex"><span class="text-primary">${item.name}</span><span
  37. class="ml-auto">${item.mobile || ''}</span></p>
  38. <span class="text-muted">${item.role || ''}</span>
  39. </dd>`
  40. })
  41. $('.book-list').empty()
  42. $('.book-list').append(html)
  43. } else {
  44. if (!$('.acc-btn').length) {
  45. accountGroup.forEach((group, idx) => {
  46. if (!group) return
  47. html += `<dt><a href="javascript: void(0);" class="acc-btn" data-groupid="${idx}" data-type="hide"><i class="fa fa-plus-square"></i>
  48. </a> ${group.groupName}</dt>
  49. <div class="dd-content" data-toggleid="${idx}">`
  50. group.groupList.forEach(item => {
  51. if (item.id !== cur_uid) {
  52. html += `<dd class="border-bottom p-2 mb-0 " data-id="${item.id}" >
  53. <p class="mb-0 d-flex"><span class="text-primary">${item.name}</span><span
  54. class="ml-auto">${item.mobile || ''}</span></p>
  55. <span class="text-muted">${item.role || ''}</span>
  56. </dd>`
  57. }
  58. });
  59. html += '</div>'
  60. })
  61. $('.book-list').empty()
  62. $('.book-list').append(html)
  63. }
  64. }
  65. }, 400);
  66. })
  67. // 添加审批流程按钮逻辑
  68. $('.book-list').on('click', 'dt', function () {
  69. const idx = $(this).find('.acc-btn').attr('data-groupid')
  70. const type = $(this).find('.acc-btn').attr('data-type')
  71. if (type === 'hide') {
  72. $(this).parent().find(`div[data-toggleid="${idx}"]`).show(() => {
  73. $(this).children().find('i').removeClass('fa-plus-square').addClass('fa-minus-square-o')
  74. $(this).find('.acc-btn').attr('data-type', 'show')
  75. })
  76. } else {
  77. $(this).parent().find(`div[data-toggleid="${idx}"]`).hide(() => {
  78. $(this).children().find('i').removeClass('fa-minus-square-o').addClass('fa-plus-square')
  79. $(this).find('.acc-btn').attr('data-type', 'hide')
  80. })
  81. }
  82. return false
  83. })
  84. // 添加到审批流程中
  85. $('dl').on('click', 'dd', function () {
  86. const id = parseInt($(this).data('id'))
  87. if (id !== 0) {
  88. postData(preUrl + '/audit/add', { auditorId: id }, (data) => {
  89. // <p class="m-0 ml-2"><small class="text-muted">中交第一公路工程局有限公司国道311线满别公路施工一分部</small></p>
  90. const html = []
  91. html.push('<li class="list-group-item" auditorId="'+ data.audit_id +'"><a href="javascript: void(0)" class="text-danger pull-right">移除</a>')
  92. html.push('<span>')
  93. html.push(data.order + ' ')
  94. html.push(data.name + ' ')
  95. html.push('</span>')
  96. html.push('<small class="text-muted">')
  97. html.push(data.role)
  98. html.push('</small>')
  99. html.push(`<p class="m-0 ml-2"><small class="text-muted">${data.company}</small></p></li>`)
  100. $('#auditors').append(html.join(''))
  101. if ($('.fa-stop-circle').length) {
  102. $('.fa-stop-circle').removeClass('fa-stop-circle').addClass('fa-chevron-circle-down')
  103. }
  104. const auditorsHTML = `<li class="list-group-item" data-auditorId='${data.audit_id}'><i class="fa fa fa-stop-circle" ></i> ${data.name} <small class="text-muted">${data.role}</small></li>`
  105. $('#auditors2').append(auditorsHTML)
  106. if ($('#auditors')[0].children.length > 0) {
  107. checkModal(false)
  108. }
  109. });
  110. }
  111. });
  112. // 删除审批人
  113. $('body').on('click', '#auditors li>a', function () {
  114. const li = $(this).parent()
  115. const data = {
  116. auditorId: parseInt(li.attr('auditorId')),
  117. };
  118. postData(preUrl + '/audit/delete', data, (result) => {
  119. li.remove();
  120. for (const rst of result) {
  121. const aLi = $('li[auditorId=' + rst.audit_id + ']');
  122. $('span', aLi).text(rst.order + ' ' + rst.name + ' ')
  123. }
  124. // 删除左边审核人
  125. $(`#auditors2 li[data-auditorId='${data.auditorId}']`).remove()
  126. })
  127. })
  128. $('#au-btn').on('click','a', function() {
  129. const content = $(this).data('target')
  130. switch (content) {
  131. case '#sub-sp':
  132. if ($('#auditors')[0].children.length) {
  133. checkModal(false)
  134. } else {
  135. checkModal(true)
  136. }
  137. break;
  138. default:
  139. break;
  140. }
  141. })
  142. // 上报审批
  143. $('#tm-submit').click(function() {
  144. const pay_ratio = parseFloat($(`.pay-input[data-type=0]`).val())
  145. const cur_amount = parseFloat(parseFloat($(`.pay-input[data-type=1]`).val()).toFixed(decimal))
  146. if (!pay_ratio || !cur_amount) {
  147. return toastr.error('请填写本期金额!')
  148. }
  149. const prev_amount = prevAdvance && prevAdvance.prev_total_amount || 0
  150. const prev_total_amount = ZhCalc.add(cur_amount, prev_amount)
  151. const remark = filterText($('#ad-remark').val())
  152. const data = {pay_ratio, cur_amount, prev_amount, prev_total_amount, remark, status: auditConst.status.checking}
  153. postData(preUrl + '/audit/start', data, (data) => {
  154. window.location.reload()
  155. }, () => {
  156. window.location.reload()
  157. })
  158. })
  159. // 重新上报
  160. $('#sp-list2-btn').click(() => {
  161. $('#tm-submit').trigger('click')
  162. })
  163. // 转化成两位小数
  164. function fixedToSub(s, decimal = 2) {
  165. return parseFloat(parseFloat(s).toFixed(decimal))
  166. }
  167. // 自动转换支付比例和本期金额
  168. $('.pay-input').on('change', function(e) {
  169. let val = parseFloat(e.target.value)
  170. const p_amount = prevAdvance && prevAdvance.prev_total_amount || 0 // 截止本期金额
  171. const re_amount = ZhCalc.sub(advancePayTotal, p_amount) // 剩余未付款的总额
  172. const min = parseFloat($(this).attr('min'))
  173. const max = parseFloat($(this).attr('max'))
  174. const type = parseInt($(this).data('type'))
  175. let pay_ratio = null
  176. let cur_amount = null
  177. if (val < min) {
  178. // 限制最小值为min
  179. $(this).val(min)
  180. val = min
  181. }
  182. if (max && val > max) {
  183. // 限制最大值为max
  184. $(this).val(max)
  185. val = max
  186. }
  187. // 本期金额转化
  188. if (type === 1) {
  189. if (val > re_amount) {
  190. // 限制不能超过最大值
  191. val = re_amount
  192. }
  193. // $(this).val(fixedToSub(val, decimal)) // 重新赋值限制只有两位小数
  194. const pay_a_input = $(`.pay-input[data-type=${reverse(type)}]`)
  195. pay_ratio = parseFloat(ZhCalc.mul(ZhCalc.div(val, advancePayTotal), 100).toFixed(2))
  196. cur_amount = val
  197. pay_a_input.val(pay_ratio)
  198. const total = parseFloat(ZhCalc.add(val, p_amount).toFixed(decimal)).toString().split('.')[1]
  199. // 截止本期金额文案更新
  200. $('#p_total2').text(formatMoney(ZhCalc.add(val, p_amount), ',', total && total.length || 0) + '元')
  201. } else {
  202. if (val.toFixed(1) === max.toFixed(1)) {
  203. val = max
  204. }
  205. // 支付比例转化
  206. $(this).val(fixedToSub(val)) // 重新赋值限制只有两位小数
  207. const cur_m_input = $(`.pay-input[data-type=${reverse(type)}]`)
  208. cur_amount = ZhCalc.round(ZhCalc.mul(advancePayTotal, ZhCalc.div(val, 100)), decimal)
  209. pay_ratio = val
  210. cur_m_input.val(parseFloat(cur_amount.toFixed(decimal)))
  211. const total = parseFloat(ZhCalc.add(cur_amount, p_amount).toFixed(decimal)).toString().split('.')[1]
  212. // 截止本期金额文案更新
  213. $('#p_total2').text(formatMoney(ZhCalc.add(cur_amount, p_amount), ',', total && total.length || 0) + '元')
  214. }
  215. const data = {
  216. pay_ratio,
  217. cur_amount,
  218. }
  219. oldVal = {
  220. cur_amount: parseFloat($(`.pay-input[data-type=${1}]`).val()),
  221. remark: filterText($('#ad-remark').val())
  222. }
  223. clearTimeout(timer)
  224. timer = setTimeout(() => {
  225. if (checkInput()) {
  226. update(data)
  227. clearTimeout(timer)
  228. }
  229. }, 500);
  230. })
  231. function checkInput() {
  232. const newVal = {
  233. cur_amount: parseFloat($(`.pay-input[data-type=${1}]`).val()),
  234. remark: filterText($('#ad-remark').val())
  235. }
  236. return newVal.cur_amount === oldVal.cur_amount && newVal.remark === oldVal.remark
  237. }
  238. $('#ad-remark').on('change', function(e) {
  239. const remark = filterText(e.target.value);
  240. oldVal = {
  241. pay_ratio: parseFloat($(`.pay-input[data-type=${0}]`).val()),
  242. cur_amount: parseFloat($(`.pay-input[data-type=${1}]`).val()),
  243. remark
  244. }
  245. const data = oldVal
  246. clearTimeout(timer)
  247. timer = setTimeout(() => {
  248. if (checkInput()) {
  249. update(data)
  250. clearTimeout(timer)
  251. }
  252. }, 500);
  253. })
  254. function filterText(text) {
  255. if (!text) return null
  256. return text.replace(/(\r\n)|(\n)/g, '<br/>').replace(/\s/g, ' ')
  257. }
  258. function update(data) {
  259. postData(preUrl + '/update', data)
  260. }
  261. // $('#file-modal-target').click(function () {
  262. // $('#file-modal').trigger('click')
  263. // })
  264. $('#file-ok').click(function () {
  265. const files = Array.from($('#file-modal')[0].files)
  266. const valiData = files.map(v => {
  267. const ext = v.name.substring(v.name.lastIndexOf('.') + 1)
  268. return {
  269. size: v.size,
  270. ext
  271. }
  272. })
  273. if (validateFiles(valiData)) {
  274. if (files.length) {
  275. const formData = new FormData()
  276. files.forEach(file => {
  277. formData.append('name', file.name)
  278. formData.append('size', file.size)
  279. formData.append('file', file)
  280. })
  281. postDataWithFile(preUrl + '/file/upload', formData, function (result) {
  282. handleFileList(result)
  283. $('#file-cancel').click()
  284. });
  285. }
  286. }
  287. })
  288. function handleFileList(files = []) {
  289. $('#file-content').empty()
  290. const { uncheck, checkNo } = auditConst.status
  291. const newFiles = files.map(file => {
  292. let showDel = false;
  293. if (file.uid === cur_uid) {
  294. if (!curAuditor) {
  295. advance.status === uncheck && cur_uid === advance.uid && (showDel = true)
  296. advance.status === checkNo && cur_uid === advance.uid && (showDel = true)
  297. } else {
  298. curAuditor.audit_id === cur_uid && (showDel = true)
  299. }
  300. }
  301. return {...file, showDel}
  302. })
  303. let html = `<tr><td colspan="3"><a href="#addfujian" data-toggle="modal" class="btn btn-sm btn-light text-primary" data-placement="bottom" title="" data-original-title="添加清单"><i class="fa fa-cloud-upload" aria-hidden="true"></i> 上传附件</a></td></tr>`
  304. newFiles.forEach((file, idx) => {
  305. if (file.showDel) {
  306. html += `<tr><td width="70">${idx + 1}</td><td><a href="/${file.filepath}" target="_blank">${file.filename}</a></td><td width="90"><a href="javascript: void(0);" class="text-danger file-del" data-id="${file.id}">移除</a></td></tr>`
  307. } else {
  308. html += `<tr><td width="70">${idx + 1}</td><td><a href="/${file.filepath}" target="_blank">${file.filename}</a></td><td width="90"></td></tr>`
  309. }
  310. })
  311. $('#file-content').append(html)
  312. }
  313. $('#file-content').on('click', 'a', function () {
  314. if ($(this).hasClass('file-del')) {
  315. const id = $(this).data('id')
  316. postData(preUrl + '/file/del', {id}, (result) => {
  317. handleFileList(result)
  318. })
  319. }
  320. })
  321. })
  322. /**
  323. * 校验文件大小、格式
  324. * @param {Array} files 文件数组
  325. */
  326. function validateFiles(files) {
  327. if (files.length > 10) {
  328. toastr.error('至多同时上传10个文件');
  329. return false
  330. }
  331. return files.every(file => {
  332. if (file.size > 1024 * 1024 * 30) {
  333. toastr.error('文件大小限制为30MB');
  334. return false
  335. }
  336. if (whiteList.indexOf('.' + file.ext) === -1) {
  337. toastr.error('请上传正确的格式文件');
  338. return false
  339. }
  340. return true
  341. })
  342. }
  343. function reverse(num){
  344. return 1^num
  345. }
  346. function formatMoney(s, dot = ',', decimal = 2) {
  347. if (!s) {
  348. s = 0;
  349. return s.toFixed(decimal);
  350. }
  351. s = parseFloat((s + '').replace(/[^\d\.-]/g, '')).toFixed(decimal) + '';
  352. if (!decimal) {
  353. s += '.';
  354. }
  355. const l = s.split('.')[0].split('').reverse(),
  356. r = s.split('.')[1];
  357. let t = '';
  358. for (let i = 0; i < l.length; i++) {
  359. t += l[i] + ((i + 1) % 3 == 0 && (i + 1) != l.length ? dot : '');
  360. }
  361. return t.split('').reverse().join('') + (decimal === 0 ? '' : '.' + r);
  362. }