Leave.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. <template>
  2. <div class="leave">
  3. <m-header v-if="headerStatus" />
  4. <van-cell-group class="search">
  5. <van-field label="开始时间" placeholder="选择开始时间" input-align="right"
  6. v-model="searchList.startText" readonly is-link
  7. @click="startShow = true" />
  8. <van-field label="结束时间" input-align="right" placeholder="选择结束时间"
  9. v-model="searchList.endText" readonly is-link
  10. @click="endShow = true" />
  11. <!-- <van-field label="请假类型" is-link input-align="right" placeholder="选择请假类型"
  12. v-model="searchList.dealText" readonly clickable
  13. @click="dealShow = true" /> -->
  14. <van-field type="textarea" v-model="searchList.remark" placeholder="请详细说明原因"
  15. rows="4" autosize />
  16. </van-cell-group>
  17. <van-panel title="课时安排" v-if="vipList.length > 0">
  18. <template v-for="(item, index) in vipList">
  19. <div class="leaveCell" v-if="item.type == 'VIP'" :key="index">
  20. <div class="leaveCell-l">{{ item.name }}</div>
  21. <div class="leaveCell-r">
  22. <div class="left-wrap">
  23. <p class="classTime">上课时间</p>
  24. <p>{{ item.classDate | getFormatTime(item.startClassTime) }}</p>
  25. <div class="line"></div>
  26. <img src="@/assets/images/switch-icon.png"
  27. alt=""
  28. class="icon">
  29. </div>
  30. <div class="left-wrap" v-if="item.changeTime">
  31. <p class="classTime">已调整为</p>
  32. <p>{{ item.changeTime }} <van-icon @click="onUpdate(item)" name="edit" /></p>
  33. </div>
  34. <div class="left-wrap" v-else>
  35. <van-button @click="onAdd(item)" round type="info" size="small">调整</van-button>
  36. </div>
  37. </div>
  38. </div>
  39. </template>
  40. </van-panel>
  41. <div class="button-group">
  42. <van-button type="primary" @click="onSubmit" round size="large">确认</van-button>
  43. </div>
  44. <!-- 开始时间弹窗 -->
  45. <van-popup v-model="startShow" position="bottom">
  46. <van-datetime-picker
  47. v-model="startDate.currentDate"
  48. type="datetime"
  49. :item-height="40"
  50. title="开始时间"
  51. :min-date="startDate.minDate"
  52. :max-date="startDate.maxDate"
  53. @cancel="startShow = false"
  54. @confirm="onStartConfirm"
  55. :formatter="formatter" />
  56. </van-popup>
  57. <!-- 结束时间弹窗 -->
  58. <van-popup v-model="endShow" position="bottom">
  59. <van-datetime-picker
  60. v-model="endDate.currentDate"
  61. type="datetime"
  62. :item-height="40"
  63. title="结束时间"
  64. :min-date="endDate.minDate"
  65. :max-date="endDate.maxDate"
  66. @cancel="endShow = false"
  67. @confirm="onEndConfirm"
  68. :formatter="formatter" />
  69. </van-popup>
  70. <van-action-sheet
  71. v-model="dealShow"
  72. :actions="leaveCategoryList"
  73. cancel-text="取消"
  74. @cancel="dealShow = false"
  75. @select="onDealSelect"/>
  76. <!-- 调整时间 -->
  77. <van-popup v-model="changeShow" position="bottom">
  78. <van-datetime-picker
  79. v-model="changeDate.currentDate"
  80. type="datetime"
  81. :item-height="40"
  82. title="结束时间"
  83. :min-date="changeDate.minDate"
  84. :max-date="changeDate.maxDate"
  85. @cancel="changeShow = false"
  86. @confirm="onChangeConfirm"
  87. :formatter="formatter" />
  88. </van-popup>
  89. </div>
  90. </template>
  91. <script>
  92. /* eslint-disable */
  93. import MHeader from '@/components/MHeader'
  94. import { queryVipCourseScheduleList, leaveCategoryPage, askForLeave } from '@/api/teacher'
  95. import { browser } from '@/common/common'
  96. // let nowTime = new Date()
  97. // let changeTime = new Date(nowTime.setDate(nowTime.getDate() + 1))
  98. export default {
  99. name: 'leave',
  100. components: { MHeader },
  101. data() {
  102. return {
  103. headerStatus: false,
  104. startShow: false,
  105. startDate: { // 开始时间
  106. minDate: new Date(),
  107. maxDate: new Date(2025, 12, 31),
  108. currentDate: new Date()
  109. },
  110. endShow: false,
  111. endDate: { // 结束时间
  112. minDate: new Date(),
  113. maxDate: new Date(2025, 12, 31),
  114. currentDate: new Date()
  115. },
  116. dealShow: false,
  117. searchList: {
  118. startText: null,
  119. endText: null,
  120. dealText: null,
  121. remark: null
  122. },
  123. vipList: [], // 申请调整的vip列表
  124. changeShow: false,
  125. changeDate: { // 结束时间
  126. minDate: new Date(),
  127. maxDate: new Date(2025, 12, 31),
  128. currentDate: new Date()
  129. },
  130. leaveCategoryList: [],
  131. changeItem: null,
  132. }
  133. },
  134. mounted() {
  135. let params = this.$route.query
  136. if(params.Authorization) {
  137. localStorage.setItem('Authorization', params.Authorization)
  138. localStorage.setItem('userInfo', params.Authorization)
  139. }
  140. document.title = '批量调整'
  141. // if(browser().android) {
  142. // this.headerStatus = true
  143. // }
  144. this.__init()
  145. },
  146. methods: {
  147. __init() {
  148. leaveCategoryPage({
  149. rows: 9999,
  150. page: 1
  151. }).then(res => {
  152. let result = res.data
  153. if(result.code == 200) {
  154. result.data.rows.forEach(item => {
  155. this.leaveCategoryList.push({
  156. name: item.name,
  157. id: item.id
  158. })
  159. })
  160. }
  161. })
  162. },
  163. getDateInfo(value) { // 获取时间
  164. let tempValue = value
  165. if(typeof value !== 'object') {
  166. tempValue = value.replace(/-/ig, '/')
  167. }
  168. let d = new Date(tempValue)
  169. let hour = d.getHours() >= 10 ? d.getHours() : '0' + d.getHours()
  170. let minute = d.getMinutes() >= 10 ? d.getMinutes() : '0' + d.getMinutes()
  171. return hour + ':' + minute + ':00'
  172. },
  173. onSubmit() {
  174. let searchList = this.searchList
  175. if(!searchList.startText || !searchList.endText) {
  176. this.$toast('时间不能为空')
  177. return
  178. }
  179. // if(!searchList.dealText) {
  180. // this.$toast('请选择请假类型')
  181. // return
  182. // }
  183. if(!searchList.remark) {
  184. this.$toast('请填写原因')
  185. return
  186. }
  187. let leaveCategoryId
  188. this.leaveCategoryList.forEach(item => {
  189. if(item.name == searchList.dealText) {
  190. leaveCategoryId = item.id
  191. }
  192. })
  193. let coursesScheduleJson = []
  194. let status = false
  195. this.vipList.forEach(item => {
  196. if(!item.changeAllTime && item.type == 'VIP') {
  197. this.$toast('操作无效:您还有VIP未调整')
  198. status = true
  199. }
  200. let tempI = {}
  201. if(item.type == 'VIP') {
  202. tempI = Object.assign({}, item)
  203. let startStr = '2019/12/18 ' + this.getDateInfo(item.startClassTime),
  204. endStr = '2019/12/18 ' + this.getDateInfo(item.endClassTime)
  205. let startDate = new Date(startStr),
  206. endDate = new Date(endStr)
  207. let m = parseInt(Math.abs(startDate.getTime() - endDate.getTime()) / 1000 / 60)
  208. tempI.classDate = this.getFormatDate(item.changeAllTime) + ':00'
  209. tempI.startClassTime = this.getFormatDate(item.changeAllTime) + ':00'
  210. let currentDate = new Date(item.changeAllTime)
  211. currentDate.setMinutes(currentDate.getMinutes() + m)
  212. tempI.endClassTime = this.getFormatDate(currentDate) + ':00'
  213. }
  214. coursesScheduleJson.push({
  215. before: item,
  216. after: tempI
  217. })
  218. })
  219. if(status) return
  220. askForLeave({
  221. coursesScheduleJson: JSON.stringify(coursesScheduleJson),
  222. startTime: searchList.startText,
  223. endTime: searchList.endText,
  224. leaveCategoryId: leaveCategoryId,
  225. leaveCategoryName: searchList.dealText,
  226. remark: searchList.remark
  227. }).then(res => {
  228. let result = res.data
  229. if(result.code == 200) {
  230. this.$toast('申请成功')
  231. setTimeout(() => {
  232. if(browser().iPhone) {
  233. window.webkit.messageHandlers.DAYA.postMessage(JSON.stringify({api: 'back'}))
  234. } else if(browser().android) {
  235. DAYA.postMessage(JSON.stringify({api: 'back'}))
  236. } else {
  237. this.$router.push('/business')
  238. }
  239. }, 500)
  240. } else {
  241. this.$toast(result.msg)
  242. }
  243. })
  244. },
  245. onAdd(item) { // 调整
  246. this.changeShow = true
  247. this.changeItem = item
  248. },
  249. onUpdate(item) {
  250. this.changeDate.currentDate = item.changeAllTime
  251. this.changeShow = true
  252. this.changeItem = item
  253. },
  254. onChangeConfirm(val) {
  255. let tempDate = new Date(val)
  256. let month = (tempDate.getMonth() + 1) >= 10 ? (tempDate.getMonth() + 1) : '0' + (tempDate.getMonth() + 1)
  257. let day = tempDate.getDate() >= 10 ? tempDate.getDate() : '0' + tempDate.getDate()
  258. let hours = tempDate.getHours() >= 10 ? tempDate.getHours() : '0' + tempDate.getHours()
  259. let min = tempDate.getMinutes() >= 10 ? tempDate.getMinutes() : '0' + tempDate.getMinutes()
  260. this.changeItem.changeTime = month + '-' + day + ' ' + hours + ':' + min
  261. this.changeItem.changeAllTime = val
  262. this.changeShow = false
  263. },
  264. onStartConfirm(val) { // 开始时间
  265. let searchList = this.searchList
  266. searchList.startText = this.getFormatDate(val)
  267. this.startShow = false
  268. if(val >= this.endDate.currentDate) {
  269. searchList.endText = null
  270. this.endDate.currentDate = new Date()
  271. } else {
  272. if(searchList.startText && searchList.endText) {
  273. this.queryVipCourseScheduleList()
  274. }
  275. }
  276. },
  277. onEndConfirm(val) { // 结束时间
  278. let searchList = this.searchList
  279. searchList.endText = this.getFormatDate(val)
  280. this.endShow = false
  281. if(val <= this.startDate.currentDate) {
  282. searchList.startText = null
  283. this.startDate.currentDate = new Date()
  284. } else {
  285. if(searchList.startText && searchList.endText) {
  286. this.queryVipCourseScheduleList()
  287. }
  288. }
  289. },
  290. queryVipCourseScheduleList() { // 获取需要调整的VIP课
  291. queryVipCourseScheduleList({
  292. endTime: this.searchList.endText,
  293. startTime: this.searchList.startText
  294. }).then(res => {
  295. let result = res.data
  296. this.vipList = []
  297. if(result.code == 200 && result.data.length > 0) {
  298. this.vipList = result.data
  299. }
  300. })
  301. },
  302. onDealSelect(val) {
  303. // 交易收支
  304. this.searchList.dealText = val.name
  305. this.dealShow = false
  306. },
  307. getFormatDate(data) {
  308. let tempDate = new Date(data)
  309. let month = (tempDate.getMonth() + 1) >= 10 ? (tempDate.getMonth() + 1) : '0' + (tempDate.getMonth() + 1)
  310. let day = tempDate.getDate() >= 10 ? tempDate.getDate() : '0' + tempDate.getDate()
  311. let tDate = tempDate.getFullYear() + '-' + month + '-' + day
  312. let hours = tempDate.getHours() >= 10 ? tempDate.getHours() : '0' + tempDate.getHours()
  313. let min = tempDate.getMinutes() >= 10 ? tempDate.getMinutes() : '0' + tempDate.getMinutes()
  314. return tDate + ' ' + hours + ':' + min
  315. },
  316. formatter(type, value) { // 格式化时间
  317. if (type === 'year') {
  318. return `${value}年`;
  319. } else if (type === 'month') {
  320. return `${value}月`
  321. } else if(type === 'day') {
  322. return `${value}日`
  323. } else if(type === 'hour') {
  324. return `${value}时`
  325. } else if(type === 'minute') {
  326. return `${value}分`
  327. }
  328. return value
  329. }
  330. },
  331. filters: {
  332. getFormatTime(tempA, tempB) {
  333. tempA = new Date(tempA.replace(/-/g, "/")),
  334. tempB = new Date(tempB.replace(/-/g, "/"))
  335. let month = Number(tempA.getMonth() + 1) >= 10 ? Number(tempA.getMonth() + 1) : '0' + Number(tempA.getMonth() + 1)
  336. let day = Number(tempA.getDate()) >= 10 ? tempA.getDate() : '0' + tempA.getDate()
  337. let hours = Number(tempB.getHours()) >= 10 ? tempB.getHours() : '0' + tempB.getHours()
  338. let min = Number(tempB.getMinutes()) >= 10 ? tempB.getMinutes() : '0' + tempB.getMinutes()
  339. return month + '-' + day + ' ' + hours + ':' + min
  340. }
  341. }
  342. }
  343. </script>
  344. <style lang='less' scoped>
  345. @import url('../../assets/commonLess/variable.less');
  346. .leave {
  347. min-height: 100vh;
  348. overflow: hidden;
  349. }
  350. .search .van-cell {
  351. padding: .13rem .16rem;
  352. font-size: .14rem;
  353. }
  354. .result {
  355. margin-top: .1rem;
  356. .count {
  357. font-size: .12rem;
  358. color: @tFontColor;
  359. }
  360. .add {
  361. color: @orangeColor;
  362. }
  363. }
  364. /deep/.van-panel {
  365. margin-top: .1rem;
  366. .van-cell__title {
  367. font-size: .16rem;
  368. color: @mFontColor;
  369. }
  370. }
  371. .leaveCell {
  372. position: relative;
  373. display: flex;
  374. flex-direction: row;
  375. // justify-content: space-between;
  376. align-items: center;
  377. padding: 0.15rem;
  378. border-bottom: 1px solid #f3f4f8;
  379. font-size: .14rem;
  380. &:last-child {
  381. border-bottom: 0;
  382. }
  383. .leaveCell-l {
  384. flex-basis: .8rem;
  385. padding-right: .08rem
  386. }
  387. .leaveCell-r {
  388. display: flex;
  389. flex-direction: row;
  390. justify-content: space-around;
  391. align-items: center;
  392. .left-wrap {
  393. .classTime {
  394. margin-bottom: 0.06rem;
  395. }
  396. min-width: 1rem;
  397. position: relative;
  398. &:first-child {
  399. padding-right: 0.15rem;
  400. }
  401. &:last-child {
  402. padding-left: 0.15rem;
  403. }
  404. .line {
  405. position: absolute;
  406. width: 1px;
  407. height: 0.56rem;
  408. background-color: #f3f3f8;
  409. right: 0;
  410. top: -0.07rem;
  411. }
  412. .icon {
  413. position: absolute;
  414. width: 0.15rem;
  415. height: 0.15rem;
  416. right: -0.07rem;
  417. top: 0.15rem;
  418. }
  419. }
  420. }
  421. }
  422. /deep/.van-icon-edit {
  423. color: @mColor;
  424. font-size: .16rem;
  425. vertical-align: text-bottom;
  426. margin-left: .08rem;
  427. }
  428. .button-group {
  429. margin: .3rem .26rem .2rem;
  430. .van-button--primary {
  431. background: @mColor;
  432. font-size: .18rem;
  433. }
  434. }
  435. </style>