back_school.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535
  1. <template>
  2. <view class="container">
  3. <!-- 分段器区域 -->
  4. <common-controlTag :tagList="tagList" :currentIndex="currentIndex" @change="changeIndex"></common-controlTag>
  5. <!-- 发起提交区域 -->
  6. <view class="submit" v-if="currentIndex == 0">
  7. <!-- 校友姓名区域 -->
  8. <view class="box">
  9. <view class="box_title">
  10. <text class="text">*</text>
  11. 校友姓名
  12. </view>
  13. <view class="box_input">
  14. <input class="input" placeholder-style="color:#A6A6A6" placeholder="请输入校友姓名" v-model="form.name" />
  15. </view>
  16. </view>
  17. <!-- 微卡区域 -->
  18. <view class="box">
  19. <view class="box_title">
  20. <text class="text">*</text>
  21. 微校卡号
  22. </view>
  23. <view class="box_input">
  24. <input class="input" placeholder-style="color:#A6A6A6" placeholder="请输入微卡" v-model="form.cardNumber" />
  25. </view>
  26. </view>
  27. <!-- 手机区域 -->
  28. <view class="box">
  29. <view class="box_title">
  30. <text class="text">*</text>
  31. 手机
  32. </view>
  33. <view class="box_input">
  34. <input class="input" placeholder-style="color:#A6A6A6" placeholder="请输入手机" v-model="form.phone" />
  35. </view>
  36. </view>
  37. <!-- 校区区域 -->
  38. <view class="box">
  39. <view class="box_title">
  40. <text class="text">*</text>
  41. 校区
  42. </view>
  43. <picker :range="schoolRange" range-key="name" @change="changeSchool">
  44. <view class="box_input">
  45. <view class="picker" :class="{ pick: form.school }">{{ form.school ? form.school : '请选择校区' }}</view>
  46. <uni-icons type="down" size="24" color="#A6A6A6"></uni-icons>
  47. </view>
  48. </picker>
  49. </view>
  50. <!-- 返校日期区域 -->
  51. <view class="box">
  52. <view class="box_title">
  53. <text class="text">*</text>
  54. 返校日期
  55. </view>
  56. <picker mode="date" :start="dayjs(Date.now()).format('YYYY-MM-DD')" @change="changeBackTime">
  57. <view class="box_input">
  58. <view class="picker" :class="{ pick: form.returnsTime }">{{ form.returnsTime ? form.returnsTime : '请选择返校日期' }}</view>
  59. <uni-icons type="down" size="24" color="#A6A6A6"></uni-icons>
  60. </view>
  61. </picker>
  62. </view>
  63. <!-- 离校日期区域 -->
  64. <view class="box">
  65. <view class="box_title">
  66. <text class="text">*</text>
  67. 离校日期
  68. </view>
  69. <picker mode="date" :start="dayjs(Date.now()).format('YYYY-MM-DD')" @change="changeLeaveTime">
  70. <view class="box_input">
  71. <view class="picker" :class="{ pick: form.returneTime }">{{ form.returneTime ? form.returneTime : '请选择离校日期' }}</view>
  72. <uni-icons type="down" size="24" color="#A6A6A6"></uni-icons>
  73. </view>
  74. </picker>
  75. </view>
  76. <!-- 返校事由区域 -->
  77. <view class="box">
  78. <view class="box_title">
  79. <text class="text">*</text>
  80. 返校事由
  81. </view>
  82. <view class="box_textarea">
  83. <textarea v-model="form.remark" class="textarea" :maxlength="-1" placeholder="请输入返校事由"></textarea>
  84. </view>
  85. </view>
  86. <view class="btn" @click="handleSubmit">提交</view>
  87. </view>
  88. <!-- 提交记录区域 -->
  89. <view class="record" v-if="currentIndex == 1">
  90. <!-- 选择时间区域 -->
  91. <view class="time">
  92. <view class="time_box" :class="{ active: currentIndex_time == index }" v-for="(item, index) in timeList" :key="item.id" @click="changeTimeIndex(index)">
  93. {{ item.name }}
  94. </view>
  95. </view>
  96. <!-- 列表区域 -->
  97. <view class="list">
  98. <!-- 每一个记录区域 -->
  99. <view class="list_box" v-for="item in dataList" :key="item.id">
  100. <!-- 状态区域 -->
  101. <view class="status pass">{{ item.passName }}</view>
  102. <view>姓名:{{ item.name }}</view>
  103. <view>微卡:{{ item.cardNumber }}</view>
  104. <view>手机:{{ item.phone }}</view>
  105. <view>校区:{{ item.schoolName }}</view>
  106. <view>返校日期:{{ item.returnTime }}</view>
  107. <view>创建时间:{{ item.createTime }}</view>
  108. <view>返校事由:</view>
  109. <view>
  110. {{ item.remark }}
  111. </view>
  112. </view>
  113. </view>
  114. <!-- 没有数据时展示的页面 -->
  115. <noData v-if="!dataList.length"></noData>
  116. </view>
  117. </view>
  118. </template>
  119. <script setup>
  120. import { onLoad, onReachBottom } from '@dcloudio/uni-app'
  121. import { ref } from 'vue'
  122. import dayjs from 'dayjs'
  123. import { getSchoolData, getInsertReturnData, getWeekTypes, getApplicationReturn } from '@/api/index.js'
  124. // 分段器数组
  125. const tagList = ['发起提交', '提交记录']
  126. // 分段器当前索引
  127. const currentIndex = ref(0)
  128. // 时间分段器数组
  129. const timeList = ref([])
  130. // 时间分段器当前索引
  131. const currentIndex_time = ref(0)
  132. // 校区数组
  133. const schoolRange = ref([])
  134. // 提交数据
  135. const form = ref({
  136. // 姓名
  137. name: '',
  138. // 微校卡号
  139. cardNumber: '',
  140. // 手机
  141. phone: '',
  142. // 校区(显示)
  143. school: '',
  144. // 校区(参数)
  145. schoolId: '',
  146. // 返校日期
  147. returnsTime: '',
  148. // 离校日期
  149. returneTime: '',
  150. // 返校事由
  151. remark: ''
  152. })
  153. // 当前页
  154. const currentPage = ref(1)
  155. // 每页多少条
  156. const pageCount = ref(6)
  157. // 总条数
  158. const total = ref(0)
  159. // 列表数据
  160. const dataList = ref([])
  161. onLoad(() => {
  162. // 获取校区下拉列表数据
  163. getSchoolRange()
  164. })
  165. // 页面触底触发的回调
  166. onReachBottom(() => {
  167. if (currentIndex.value == 1) {
  168. if (total.value > dataList.value.length) {
  169. currentPage.value++
  170. getData()
  171. } else {
  172. uni.showToast({
  173. title: '没有更多数据了~~',
  174. icon: 'none'
  175. })
  176. }
  177. }
  178. })
  179. // 获取校区下拉列表数据
  180. const getSchoolRange = async () => {
  181. const res = await getSchoolData()
  182. // console.log(res)
  183. schoolRange.value = res.data
  184. }
  185. // 获取时间数组
  186. const getTimeData = async () => {
  187. const res = await getWeekTypes()
  188. // console.log(res)
  189. timeList.value = res.data
  190. // 获取提交记录数据
  191. getData()
  192. }
  193. // 获取提交记录数据
  194. const getData = async () => {
  195. let data = {
  196. currentPage: currentPage.value,
  197. pageCount: pageCount.value,
  198. weekType: timeList.value[currentIndex_time.value].id
  199. }
  200. const res = await getApplicationReturn(data)
  201. // console.log(res)
  202. dataList.value = [...dataList.value, ...res.data.list]
  203. total.value = res.data.totalCount
  204. }
  205. // 提交按钮回调
  206. const handleSubmit = () => {
  207. // 校验提交值是否合法
  208. let flag = checkValue()
  209. if (!flag) {
  210. uni.showModal({
  211. title: '提示',
  212. content: '确定提交吗?',
  213. success: (res) => {
  214. if (res.confirm) {
  215. submitReq()
  216. }
  217. }
  218. })
  219. }
  220. }
  221. // 校验提交值是否为空
  222. const checkValue = () => {
  223. let keyList = Object.keys(form.value)
  224. // 提示信息
  225. keyList.forEach((ele) => {
  226. // console.log(ele)
  227. if (ele == 'phone') {
  228. let regPhone = /^1[3-9]\d{9}$/
  229. if (!regPhone.test(form.value[ele])) {
  230. uni.showToast({
  231. title: `手机号码格式有误`,
  232. icon: 'none'
  233. })
  234. // 符合条件时强制打断循环
  235. keyList.length = 0
  236. }
  237. }
  238. if (form.value[ele] === '') {
  239. uni.showToast({
  240. title: `${mapValue(ele)}不能为空`,
  241. icon: 'none'
  242. })
  243. // 符合条件时强制打断循环
  244. keyList.length = 0
  245. }
  246. })
  247. // 判断是否是空值 true 为有空值
  248. let t = keyList.every((ele) => form.value[ele] === '')
  249. return t
  250. }
  251. // 映射
  252. const mapValue = (v) => {
  253. let msg = ''
  254. switch (v) {
  255. case 'name':
  256. msg = '校友姓名'
  257. break
  258. case 'cardNumber':
  259. msg = '微校卡号'
  260. break
  261. case 'phone':
  262. msg = '手机号'
  263. break
  264. case 'school':
  265. case 'schoolId':
  266. msg = '校区'
  267. break
  268. case 'returnsTime':
  269. msg = '返校日期'
  270. break
  271. case 'returneTime':
  272. msg = '离校日期'
  273. break
  274. case 'remark':
  275. msg = '返校事由'
  276. break
  277. default:
  278. msg = '内容'
  279. break
  280. }
  281. return msg
  282. }
  283. // 提交请求
  284. const submitReq = async () => {
  285. const res = await getInsertReturnData(form.value)
  286. // console.log(res)
  287. if (res.code == 200) {
  288. uni.showToast({
  289. title: '提交成功',
  290. icon: 'success'
  291. })
  292. setTimeout(() => {
  293. currentIndex.value = 1
  294. currentIndex_time.value = 0
  295. currentPage.value = 1
  296. dataList.value = []
  297. getTimeData()
  298. }, 1500)
  299. }
  300. }
  301. // 分段器切换回调
  302. const changeIndex = (e) => {
  303. // console.log(e)
  304. currentIndex.value = e
  305. uni.setNavigationBarTitle({
  306. title: currentIndex.value == 0 ? '返校申请' : '提交记录'
  307. })
  308. if (currentIndex.value == 1) {
  309. currentIndex_time.value = 0
  310. currentPage.value = 1
  311. dataList.value = []
  312. getTimeData()
  313. }
  314. }
  315. // 时间分段器切换回调
  316. const changeTimeIndex = (e) => {
  317. currentIndex_time.value = e
  318. currentPage.value = 1
  319. dataList.value = []
  320. getData()
  321. }
  322. // 选择校区时的回调
  323. const changeSchool = (e) => {
  324. let index = e.detail.value
  325. form.value.school = schoolRange.value[index].name
  326. form.value.schoolId = schoolRange.value[index].id
  327. }
  328. // 选择返校日期时的回调
  329. const changeBackTime = (e) => {
  330. form.value.returnsTime = e.detail.value
  331. }
  332. // 选择离校日期时的回调
  333. const changeLeaveTime = (e) => {
  334. form.value.returneTime = e.detail.value
  335. }
  336. </script>
  337. <style lang="scss" scoped>
  338. .container {
  339. padding: 20rpx 18rpx;
  340. min-height: 100vh;
  341. .submit {
  342. margin-top: 15rpx;
  343. .box {
  344. margin-bottom: 15rpx;
  345. font-size: 28rpx;
  346. .box_title {
  347. display: flex;
  348. margin-bottom: 15rpx;
  349. .text {
  350. color: #d43030;
  351. }
  352. }
  353. .box_input {
  354. display: flex;
  355. justify-content: space-between;
  356. align-items: center;
  357. padding: 0 22rpx;
  358. width: 710rpx;
  359. height: 80rpx;
  360. border-radius: 6rpx;
  361. background-color: #f5f5f5;
  362. .input {
  363. width: 100%;
  364. height: 100%;
  365. font-size: 28rpx;
  366. }
  367. .picker {
  368. color: #a6a6a6;
  369. overflow: hidden;
  370. white-space: nowrap;
  371. text-overflow: ellipsis;
  372. }
  373. .pick {
  374. color: #000;
  375. }
  376. }
  377. .box_textarea {
  378. width: 710rpx;
  379. height: 308rpx;
  380. border-radius: 6rpx;
  381. background-color: #f5f5f5;
  382. .textarea {
  383. box-sizing: border-box;
  384. padding: 10rpx;
  385. width: 100%;
  386. height: 100%;
  387. font-size: 28rpx;
  388. }
  389. }
  390. }
  391. .btn {
  392. display: flex;
  393. align-items: center;
  394. justify-content: center;
  395. margin: 80rpx 0;
  396. width: 710rpx;
  397. height: 80rpx;
  398. font-size: 28rpx;
  399. color: #fff;
  400. border-radius: 8rpx;
  401. background-color: #007aff;
  402. }
  403. }
  404. .record {
  405. .time {
  406. display: flex;
  407. align-items: center;
  408. justify-content: space-around;
  409. margin-top: 20rpx;
  410. width: 712rpx;
  411. height: 90rpx;
  412. font-size: 28rpx;
  413. border-radius: 8rpx;
  414. background-color: #f2f7ff;
  415. .time_box {
  416. display: flex;
  417. align-items: center;
  418. justify-content: center;
  419. width: 211rpx;
  420. height: 71rpx;
  421. border-radius: 8rpx;
  422. }
  423. .active {
  424. font-size: 30rpx;
  425. color: #0061ff;
  426. border: 2rpx solid #0061ff;
  427. background-color: rgba(0, 97, 255, 0.1);
  428. }
  429. }
  430. .list {
  431. margin-top: 30rpx;
  432. .list_box {
  433. position: relative;
  434. padding: 28rpx;
  435. margin-bottom: 20rpx;
  436. width: 714rpx;
  437. font-size: 28rpx;
  438. line-height: 50rpx;
  439. border-radius: 28rpx;
  440. box-shadow: 0 4rpx 35rpx #d3d3d3;
  441. .status {
  442. position: absolute;
  443. top: 38rpx;
  444. right: 30rpx;
  445. padding: 0 22rpx;
  446. line-height: 55rpx;
  447. color: #fff;
  448. border-radius: 70rpx 40rpx 0 70rpx;
  449. }
  450. .pass {
  451. background-image: linear-gradient(90deg, #366fff 0%, #5da0fc 100%);
  452. }
  453. .nopass {
  454. background: linear-gradient(90deg, #ff7045 0%, #f7a172 100%);
  455. }
  456. }
  457. }
  458. }
  459. }
  460. </style>