我要加班.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. _this.pageinit = function () {
  2. var that = _this
  3. _this.editInit = []
  4. newPageInit(that)
  5. }
  6. // 过滤考勤地点F7 传递变量 ,adminOrgQuery为数据源的id
  7. mbos('adminOrgQuery').bind('beforeLoad', function (e) {
  8. var params = setParams('getAtsAdminOrgUnitPlaceFilter', e.index)
  9. mbos.variable.setValue("v_entry", encodeURIComponent(JSON.stringify(params))); //赋值给变量
  10. })
  11. // 过滤加班原因F7
  12. mbos('AtsOTReasonAvailable').bind('beforeLoad', function (e) {
  13. var params = setParams('getOverTimeReasonFilter', e.index)
  14. mbos.variable.setValue("v_entry", encodeURIComponent(JSON.stringify(params))); //赋值给变量
  15. })
  16. // 过滤加班类型F7
  17. mbos('AtsOTTypeAvailable').bind('beforeLoad', function (e) {
  18. var params = setParams('getOverTimeTypeFilter', e.index)
  19. mbos.variable.setValue("v_entry", encodeURIComponent(JSON.stringify(params))); //赋值给变量
  20. })
  21. // 过滤补偿方式F7
  22. mbos('AtsOTCompensAvailable').bind('beforeLoad', function (e) {
  23. var params = setParams('getOverTimeCompensFilter', e.index)
  24. mbos.variable.setValue("v_entry", encodeURIComponent(JSON.stringify(params))); //赋值给变量
  25. })
  26. // 在页面初始化加载之后
  27. mbos('page').bind('afterLoad', function () {
  28. _this.path = mbos.pageInfo.path// 轻应用的路径编码 例如 trip880
  29. _this.detailPageCode = mbos.pageInfo.name.replace('Add', 'View') // 详情页面的编码 (个别页面可特殊处理直接写入) 例如 tripView.editui
  30. _this.operateState = mbos.getRequestParams().operateState // 'ADDNEW' 'EDIT' 'VIEW'
  31. // 初始化审批流
  32. mbos('nextperson1').checkParticipantPerson({
  33. "callback": function () { }
  34. });
  35. // 单据说明
  36. mbos('description').bind('click', function () {
  37. handleClickDesc()
  38. })
  39. getDecimal()// 获取pc配置的小数点数
  40. })
  41. mbos('entries').bind('afterRendered', function (e) {
  42. _this.decimal = 4
  43. getBillDetail(e.index) // 编辑页面渲染数据
  44. getDateType(e.index)// 判断加班日期是单选还是多选还是日期区间
  45. mbos('entries_applyOTTime', e.index).value() && (mbos('entries_applyOTTime', e.index).value()).toFixed(_this.decimal)
  46. multiLangField(e.index)// 兼容多语言字段回显的问题
  47. })
  48. // 获取pc配置的小数点数 默认为小数点后两位
  49. function getDecimal() {
  50. var callback = function (res) {
  51. _this.decimal = res.data.decimalPlaceSystem || 4
  52. }
  53. baseInterface('getDecimalPlace', callback) // 获取小数点数
  54. }
  55. // 判断加班日期是单选还是多选还是日期区间
  56. function getDateType(i) {
  57. var entry = mbos('entity').data.entries[i] // 当前明细数据
  58. if (mbos('theOtDate', 0).$attrs.datemulti == 'true') {
  59. _this.otDateType = 'dateMulti'
  60. _this.isMulDays = true
  61. mbos('entries.attAdminOrgUnit', i).hide() // 多日期隐藏考勤地点
  62. } else if (mbos('theOtDate', 0).$attrs.datescope == 'true') {
  63. _this.otDateType = 'dateScope'
  64. _this.isMulDays = true
  65. mbos('entries.attAdminOrgUnit', i).hide() // 多日期隐藏考勤地点
  66. } else {
  67. _this.otDateType = 'dateSingle'
  68. _this.isMulDays = false
  69. entry.isMulDays = false
  70. mbos('theOtDateCoordinate', i).hide() // 单日期隐藏跨天
  71. $('#theOtTime_' + i + ' .tooltip1').hide() // 单日期隐藏时间提示
  72. mbos('theOtDateCoordinate', i).attr("mustinput", false) // 取消必填校验
  73. }
  74. if (mbos.getRequestParams().operateState === "ADDNEW") {
  75. // 给【是否跨天】赋默认值【不跨天】
  76. mbos('theOtDateCoordinate', i).value({ "value": "theDayNow", "alias": localeResource.just_today })
  77. }
  78. }
  79. // 将时间格式化为时分
  80. function getHMTime(time) {
  81. return moment(time).format('HH:mm')
  82. }
  83. // 编辑页面渲染数据
  84. function getBillDetail(i) {
  85. var entry = mbos('entity').data.entries[i]
  86. entry.otDate && mbos('theOtDate', i).value(moment(entry.otDate).format('YYYY-MM-DD'))
  87. if (!_this.isMulDays) { getDateType(i) } // 未初始化时 _this.isMulDays可能为undefined
  88. console.log(entry.startTime, i, entry.endTime, mbos('entity').data.entries)
  89. if (_this.isMulDays) { // 多日期 时间的格式为时分
  90. entry.endTime && mbos('theOtTime', i).value(getHMTime(entry.startTime) + '~' + getHMTime(entry.endTime))
  91. entry.restStartTime && mbos('theRestInterval', i).value(getHMTime(entry.restStartTime) + '~' + getHMTime(entry.restEndTime))
  92. entry.restStartTime2 && mbos('theRestInterval2', i).value(getHMTime(entry.restStartTime2) + '~' + getHMTime(entry.restEndTime2))
  93. } else {
  94. entry.restTime && mbos('restTime', i).value(entry.restTime)
  95. entry.endTime && mbos('theOtTime', i).value(entry.startTime + '~' + entry.endTime) // 给加班时间赋值
  96. entry.restStartTime && mbos('theRestInterval', i).value(entry.restStartTime + '~' + entry.restEndTime) // 给休息时间赋值
  97. entry.restStartTime2 && mbos('theRestInterval2', i).value(entry.restStartTime2 + '~' + entry.restEndTime2) // 给休息时间2赋值
  98. }
  99. }
  100. // 保存按钮
  101. _this.save = function (event) {
  102. setModel()
  103. baseInterface('save', toView) // 调用保存接口
  104. }
  105. // 提交按钮
  106. _this.submit = function (event) {
  107. // 确认提交 弹框
  108. mbos.ui.showConfirm({
  109. title: localeResource.confirmSubmit,
  110. iconclass: "kdfont kdfont-zhuangtai_jingshi the_info",
  111. callback: function (data) {
  112. if (data == 0) {
  113. setModel()
  114. baseInterface('submit', toView) // 调用提交接口
  115. }
  116. }
  117. });
  118. }
  119. // 点击“保存、提交” 跳转页面
  120. function toView(res) {
  121. // 提交接口 返回的res.data为数组,取第一条数据
  122. if (res.data.keyValue || (res.data.length > 0 && res.data[0].keyValue)) {
  123. // 操作成功 提示弹框
  124. mbos.ui.showInfo({
  125. title: localeResource.succeed,
  126. iconclass: "kdfont kdfont-zhuangtai_wancheng the_success",
  127. callback: function () {
  128. openPage(_this.path, _this.detailPageCode, { billID: res.data.keyValue || res.data[0].keyValue })
  129. }
  130. });
  131. }
  132. }
  133. // 给隐藏的model赋值
  134. function setModel() {
  135. if (typeof _this.operateState != "undefined" && (_this.operateState === "ADDNEW" || _this.operateState === "EDIT")) {
  136. var entries = mbos('entity').data.entries
  137. entries.map(function (entry, index) {
  138. entry.person = easContext.person
  139. entry.position = easContext.position.id
  140. entry.adminOrgUnit = easContext.position.adminOrgUnit.id
  141. getEntries(entry, index) // 各单据处理分录数据
  142. })
  143. }
  144. }
  145. // 各单据处理分录数据的函数
  146. function getEntries(entry, i) {
  147. // 跨天方式
  148. if (mbos('theOtDateCoordinate', i).value()) {
  149. entry.theOtDateCoordinate = mbos('theOtDateCoordinate', i).value().value
  150. }
  151. entry.isMulDays = _this.isMulDays
  152. entry.otDate = _this.isMulDays ? entry.dynamic_Field1 && entry.dynamic_Field1.split(',')[0] : entry.otDate || entry.theOtDate || mbos('theOtDate', i).value() // 加班日期
  153. // 【BT-01701321】【V9.0第一轮集成测试】移动端撤回加班单后修改休息时间再提交,休息时间和加班小时数不正确。修改为休息时长60min后,再修改为休息时间0,提交后休息时间还是60
  154. if(entry.restTime === undefined){
  155. entry.restTime = ''
  156. }
  157. }
  158. // 单日期 获取默认加班类型和补偿方式
  159. function getOverTimeTypeAndOtCompens(index) {
  160. var callback = function (res) {
  161. if (res.data) {
  162. if (res.data.otTypeValue && res.data.otTypeText){
  163. mbos('entries_otType', index).value({ id: res.data.otTypeValue, name: res.data.otTypeText })
  164. } else {
  165. mbos.ui.showError(localeResource.checkShift)
  166. }
  167. res.data.compensInfo && mbos('entries_otCompens', index).value(res.data.compensInfo)
  168. }
  169. }
  170. setModel()
  171. baseInterface('getOverTimeTypeAndOtCompens', callback, index)
  172. }
  173. // 单日期 获取加班班次
  174. function getMyScheduleTime(index) {
  175. var callback = function (res) {
  176. // 默认班次存在则显示 不存在则隐藏
  177. if (res.data && res.data.defaultShift && res.data.defaultShift.name) {
  178. document.getElementById('attendanceShift_' + index).innerText = `${res.data.defaultShift.name}`
  179. $('#attendanceShift_' + index).css('display', 'flex')
  180. } else {
  181. document.getElementById('attendanceShift_' + index).innerText = ''
  182. $('#attendanceShift_' + index).css('display', 'none')
  183. }
  184. }
  185. setModel()
  186. baseInterface('getMyScheduleTime', callback, index)
  187. }
  188. // 根据起始时间计算休息分钟数
  189. function getDiffMinites(sTime, eTime, hour) {
  190. if (sTime && eTime) {
  191. // 通过正则将'-'改为'/'(ios系统不认得'-'却认得'/')
  192. var date1 = new Date(sTime.replace(/-/g, '/')).getTime()
  193. var date2 = new Date(eTime.replace(/-/g, '/')).getTime()
  194. if (sTime.split(' ')[1] && date1 > date2) { // 单日期 计算时间才需要判断
  195. mbos.ui.showError(hour ? localeResource.ot_tips : localeResource.rest_tips)
  196. return
  197. }
  198. return hour ? Math.abs((date2 - date1) / 1000 / 60 / 60) : Math.abs((date2 - date1) / 1000 / 60)
  199. }
  200. }
  201. // 获取默认休息时间
  202. function getDefaultRestTime(index) {
  203. var entry = mbos('entity').data.entries[index] // 当前明细数据
  204. var callback = function (res) {
  205. if (res.data) { // 如果无值则渲染 有值则不予更改,用户手动填写的数据优先级最高
  206. if (!mbos('theRestInterval', index).value()) {
  207. if (res.data.restEndTime) {
  208. entry.restTime = res.data.restTime
  209. mbos('theRestInterval', index).value(res.data.restStartTime + '~' + res.data.restEndTime)
  210. } else {
  211. // mbos('theRestInterval', index).value('')
  212. entry.restStartTime = ''
  213. entry.restEndTime = ''
  214. }
  215. }
  216. // 休息时间2 如果无值则渲染 有值则不予更改,用户手动填写的数据优先级最高
  217. if (!mbos('theRestInterval2', index).value()) {
  218. if (res.data.restEndTime2) {
  219. entry.restTime = res.data.restTime
  220. !mbos('theRestInterval2', index).value() && mbos('theRestInterval2', index).value(res.data.restStartTime2 + '~' + res.data.restEndTime2)
  221. } else {
  222. // mbos('theRestInterval2', index).value('')
  223. entry.restStartTime2 = ''
  224. entry.restEndTime2 = ''
  225. }
  226. }
  227. // entry.applyOTTime = ((entry.otIntervalLength * entry.days - (entry.restTime || 0) / 60) || 0).toFixed(_this.decimal) // 加班时长
  228. // 202412 加班时长改为小时数向下取整
  229. entry.applyOTTime = Math.floor((entry.otIntervalLength * entry.days - (entry.restTime || 0) / 60) || 0) ;
  230. }
  231. }
  232. if (_this.otDateType == 'dateSingle' && entry.theOtDate) {
  233. setModel()
  234. baseInterface('getMyRestTime', callback, index)
  235. }
  236. }
  237. // 单日期时判断”加班类型“是否是被禁用
  238. function isDisabledDateType(otDate, index) {
  239. var callback = function (res) {
  240. if (res.data.otrolByDateType) {
  241. mbos('entries_otType', index).disable() // 如果返回为true 则禁用
  242. } else {
  243. mbos('entries_otType', index).attr('disabled', false)
  244. }
  245. }
  246. if (otDate) {
  247. setModel()
  248. baseInterface('getAttencePolicyInfo', callback, index)
  249. }
  250. }
  251. /**
  252. * @description: 根据开始日期结束日期的时区,获取逗号拼接的日期字符串
  253. * @return {String}
  254. */
  255. function getDates(sDate, eDate) {
  256. var list = [sDate]
  257. var value = sDate
  258. while (value < eDate) {
  259. value = moment(value).add(1, 'days').format('YYYY-MM-DD')
  260. list.push(value)
  261. }
  262. return list.join(',')
  263. }
  264. // 非单日期 日期change事件
  265. function multiDateChange(dateString, entry, index) {
  266. entry.isMulDays = true
  267. entry.otDates = dateString
  268. entry.theOtDateCoordinate = 'theDayNow'
  269. entry.days = dateString.split(',').length // 天数
  270. entry.restTime = (getDiffMinites(entry.restStartTime, entry.restEndTime) + getDiffMinites(entry.restStartTime2, entry.restEndTime2)) * entry.days || 0
  271. // entry.applyOTTime = ((entry.otIntervalLength * entry.days - entry.restTime / 60) || 0).toFixed(_this.decimal)
  272. // 202412 加班时长改为小时数向下取整
  273. entry.applyOTTime = Math.floor((entry.otIntervalLength * entry.days - entry.restTime / 60) || 0);
  274. // 校验多选日期是否是同一时间类型 如果不是则清空
  275. var callback = function (res) {
  276. if (res.data && !res.data.isSameDay) {
  277. mbos.ui.showError({
  278. title: localeResource.tips,
  279. detail: localeResource.diff_type_tips,
  280. iconclass: "kdfont kdfont-zhuangtai_jingshi the_info",
  281. callback: function (data) {
  282. mbos('theOtDate', index).value(''); // 先清空
  283. mbos('theOtDate', index).open(); // 再自动打开弹框
  284. }
  285. });
  286. }
  287. }
  288. if (entry.days > 1) {
  289. setModel()
  290. baseInterface('getDateTypeIsSame', callback, index) // 校验多选日期是否是同一时间类型
  291. }
  292. // mbos('theOtTime', index).timeFormat("HH:mm")
  293. }
  294. /**
  295. * @description: 监听加班日期;
  296. * 单日期则改变 加班开始/结束时间、加班时间;
  297. 休息开始/结束时间、休息时间;
  298. 休息时长、加班时长
  299. 加班类型\加班补偿方式\加班日期班次
  300. *
  301. * 多选日期/时间区间 则改变:休息时长、加班时长
  302. *
  303. 1、pc端配置的默认加班时间;
  304. 2、默认休息时间;
  305. 3、加班类型、补偿方式接口;
  306. 4、带出对应班次;
  307. 【以上接口仅单日期触发】 【EDIT页面初始化时,不调以上4个接口】
  308. * @return {*}
  309. */
  310. _this.otDateChange = function (event) {
  311. var index = event.index
  312. var entry = mbos('entity').data.entries[index] // 当前明细数据
  313. var theOtDate = event.new_value // 加班日期
  314. if (!_this.otDateType) {
  315. getDateType(index)
  316. }
  317. if (!theOtDate) {
  318. mbos('theOtTime', index).value('')
  319. return
  320. }
  321. var otDateType = _this.otDateType // 日期类型
  322. if (otDateType == 'dateScope') { // 日期区间
  323. if (theOtDate) {
  324. var sDate = moment(theOtDate.split('~')[0]).format('YYYY-MM-DD')
  325. var eDate = theOtDate.split('~')[1] ? theOtDate.split('~')[1] : sDate
  326. theOtDate = getDates(sDate, eDate)
  327. multiDateChange(theOtDate, entry, index)
  328. }
  329. } else if (otDateType == 'dateMulti') { // 多选日期
  330. multiDateChange(theOtDate, entry, index)
  331. } else if (otDateType == 'dateSingle') { // 单选日期
  332. if (event.new_value && event.old_value && moment(event.new_value).format('YYYY-MM-DD') === moment(event.old_value).format('YYYY-MM-DD')) return
  333. theOtDate = moment(theOtDate).format('YYYY-MM-DD')
  334. entry.otDate = theOtDate
  335. entry.theOtDate = theOtDate
  336. entry.isMulDays = false
  337. getMyScheduleTime(index) // 加班班次
  338. isDisabledDateType(theOtDate, index) // 待更新到外网
  339. entry.days = 1
  340. if (!entry.startTime && !entry.endTime) {
  341. // 加班时间【00:00】 二开用户可自定义
  342. mbos('theOtTime', index).value(theOtDate + ' 00:00~' + theOtDate + ' 00:00') // 给加班时间赋默认值
  343. }
  344. getOverTimeTypeAndOtCompens(index) // 加班类型&补偿类型
  345. getDefaultRestTime(index) // 获取默认休息时间
  346. }
  347. }
  348. /**
  349. * @description: 监听加班时间:默认休息时间(调接口)
  350. * @event: applyOTTime = otIntervalLength - restTime => 加班时长 = 跨度时长 - 休息时长
  351. * @return {*}
  352. */
  353. _this.otTimeChange = function (event) {
  354. var index = event.index
  355. var theOtTime = event.new_value // 加班时间
  356. var startTime = theOtTime.split('~')[0]
  357. var endTime = theOtTime.split('~')[1]
  358. var entry = mbos('entity').data.entries[index] // 当前明细数据
  359. _this.anyDate = entry.otDates && entry.otDates.split(',')[0] || '2020-01-01' // 仅作拼接使用 无任何意义
  360. if (!theOtTime) {
  361. entry.applyOTTime = 0
  362. }
  363. startTime = _this.isMulDays ? _this.anyDate + ' ' + startTime : startTime // 确保 格式为年月日时分
  364. endTime = _this.isMulDays ? _this.anyDate + ' ' + endTime : endTime // 确保 格式为年月日时分 同一天
  365. if (startTime > endTime) { // 跨天
  366. var tomorrow = moment(_this.anyDate).add(1, 'days').format('YYYY-MM-DD')
  367. endTime = _this.isMulDays ? tomorrow + ' ' + endTime : endTime // 确保 格式为年月日时分
  368. }
  369. entry.startTime = startTime // 赋值加班开始时间
  370. entry.endTime = endTime // 赋值加班结束时间
  371. entry.otIntervalLength = getDiffMinites(startTime, endTime, 'hour') // 加班的一天跨度时长
  372. if (!entry.days) entry.days = 1
  373. // entry.applyOTTime = ((entry.otIntervalLength * entry.days - (entry.restTime || 0) / 60) || 0).toFixed(_this.decimal) // 加班时长
  374. //202412改 向下取整
  375. entry.applyOTTime = Math.floor((entry.otIntervalLength * entry.days - (entry.restTime || 0) / 60) || 0) ; // 加班时长
  376. if (mbos.getRequestParams().operateState !== 'EDIT' || _this.init) {
  377. getDefaultRestTime(index) // 更新休息时间
  378. } else {
  379. _this.init = true
  380. }
  381. }
  382. /**
  383. * @description: 监听【休息时间1】改变时长
  384. * @event:
  385. * @return {*}
  386. */
  387. _this.restTimeChange = function (event) {
  388. restChange(event, "restStartTime", "restEndTime", "restTime1")
  389. }
  390. // 监听【休息时间2】改变时长
  391. _this.restTimeChange2 = function (event) {
  392. restChange(event, "restStartTime2", "restEndTime2", "restTime2")
  393. }
  394. // 休息时间控件监听 start, end, time分别为对应的字段名
  395. function restChange(event, start, end, time) {
  396. var index = event.index
  397. // 如果两个休息时间都为空,则时间长度可编辑;否则不可编辑
  398. if (!mbos('theRestInterval', index).value() && !mbos('theRestInterval2', index).value()) {
  399. mbos('entries_restTime', index).enable()
  400. } else {
  401. mbos('entries_restTime', index).disable()
  402. }
  403. _this.anyDate = '2020-01-01' // 仅作拼接使用 无任何意义
  404. var theRestInterval = event.new_value // 休息时间
  405. var startTime = theRestInterval.split('~')[0]
  406. var endTime = theRestInterval.split('~')[1]
  407. var entry = mbos('entity').data.entries[index] // 当前明细数据
  408. var notToday = startTime > endTime // 如果开始时间大于结束时间则表示跨天了
  409. entry[start] = _this.isMulDays ? _this.anyDate + ' ' + startTime : startTime // 确保 格式为年月日时分
  410. var tomorrow = moment(_this.anyDate).add(1, 'days').format('YYYY-MM-DD')
  411. entry[end] = _this.isMulDays ? (notToday ? tomorrow + ' ' + endTime : _this.anyDate + ' ' + endTime) : endTime // 确保 格式为年月日时分
  412. entry[time] = theRestInterval ? getDiffMinites(entry[start], entry[end]) * (entry.days || 1) : 0
  413. if (entry.restTime1 == 0 && entry.restTime2 == 0) {
  414. entry.restTime = entry.restTime || 0
  415. } else {
  416. entry.restTime = (entry.restTime1 || 0) + (entry.restTime2 || 0)
  417. }
  418. // entry.applyOTTime = ((entry.otIntervalLength * entry.days - entry.restTime / 60) || 0).toFixed(_this.decimal) // 加班时长
  419. // 202412改 向下取整
  420. entry.applyOTTime = Math.floor((entry.otIntervalLength * entry.days - entry.restTime / 60) || 0) ; // 加班时长
  421. }
  422. // 休息时长改动
  423. _this.restLengthChange = function (event) {
  424. var index = event.index
  425. var entry = mbos('entity').data.entries[index] // 当前明细数据
  426. if (mbos('entries_applyOTTime', index).value()) {
  427. // entry.applyOTTime = (entry.otIntervalLength * entry.days - (event.new_value || 0) / 60 || 0).toFixed(_this.decimal)
  428. // 202412改 向下取整
  429. entry.applyOTTime = Math.floor( (entry.otIntervalLength * entry.days - (event.new_value || 0) / 60 || 0) );
  430. }
  431. }